diff --git a/rpcs3/Emu/RSX/GCM.cpp b/rpcs3/Emu/RSX/GCM.cpp index 4340c95c28..d05edeb034 100644 --- a/rpcs3/Emu/RSX/GCM.cpp +++ b/rpcs3/Emu/RSX/GCM.cpp @@ -854,7 +854,7 @@ std::string print_boolean(bool b) } } -std::string print_comparison_function(comparison_function f) +std::string to_string(comparison_function f) { switch (f) { @@ -870,7 +870,7 @@ std::string print_comparison_function(comparison_function f) throw; } -std::string print_stencil_op(stencil_op op) +std::string to_string(stencil_op op) { switch (op) { @@ -885,7 +885,7 @@ std::string print_stencil_op(stencil_op op) throw; } -std::string print_fog_mode(fog_mode op) +std::string to_string(fog_mode op) { switch (op) { @@ -899,7 +899,7 @@ std::string print_fog_mode(fog_mode op) throw; } -std::string print_logic_op(logic_op op) +std::string to_string(logic_op op) { switch (op) { @@ -922,7 +922,7 @@ std::string print_logic_op(logic_op op) throw; } -std::string print_front_face(front_face op) +std::string to_string(front_face op) { switch (op) { @@ -932,7 +932,7 @@ std::string print_front_face(front_face op) throw; } -std::string print_cull_face(cull_face op) +std::string to_string(cull_face op) { switch (op) { @@ -943,7 +943,7 @@ std::string print_cull_face(cull_face op) throw; } -std::string print_surface_target(surface_target target) +std::string to_string(surface_target target) { switch (target) { @@ -957,7 +957,7 @@ std::string print_surface_target(surface_target target) throw; } -std::string print_primitive_mode(primitive_type draw_mode) +std::string to_string(primitive_type draw_mode) { switch (draw_mode) { @@ -976,7 +976,7 @@ std::string print_primitive_mode(primitive_type draw_mode) throw; } -std::string print_transfer_operation(blit_engine::transfer_operation op) +std::string to_string(blit_engine::transfer_operation op) { switch (op) { @@ -990,7 +990,7 @@ std::string print_transfer_operation(blit_engine::transfer_operation op) throw; } -std::string print_transfer_source_format(blit_engine::transfer_source_format op) +std::string to_string(blit_engine::transfer_source_format op) { switch (op) { @@ -1011,7 +1011,7 @@ std::string print_transfer_source_format(blit_engine::transfer_source_format op) throw; } -std::string print_context_surface(blit_engine::context_surface op) +std::string to_string(blit_engine::context_surface op) { switch (op) { @@ -1021,7 +1021,7 @@ std::string print_context_surface(blit_engine::context_surface op) throw; } -std::string print_transfer_destination_format(blit_engine::transfer_destination_format op) +std::string to_string(blit_engine::transfer_destination_format op) { switch (op) { @@ -1033,7 +1033,7 @@ std::string print_transfer_destination_format(blit_engine::transfer_destination_ } -std::string print_blend_op(blend_equation op) +std::string to_string(blend_equation op) { switch (op) { @@ -1049,7 +1049,7 @@ std::string print_blend_op(blend_equation op) throw; } -std::string print_blend_factor(blend_factor factor) +std::string to_string(blend_factor factor) { switch (factor) { @@ -1072,7 +1072,7 @@ std::string print_blend_factor(blend_factor factor) throw; } -std::string print_origin_mode(window_origin origin) +std::string to_string(window_origin origin) { switch (origin) { @@ -1082,7 +1082,7 @@ std::string print_origin_mode(window_origin origin) throw; } -std::string print_pixel_center_mode(window_pixel_center in) +std::string to_string(window_pixel_center in) { switch (in) { @@ -1092,7 +1092,7 @@ std::string print_pixel_center_mode(window_pixel_center in) throw; } -std::string print_user_clip_plane_op(user_clip_plane_op op) +std::string to_string(user_clip_plane_op op) { switch (op) { @@ -1105,7 +1105,7 @@ std::string print_user_clip_plane_op(user_clip_plane_op op) -std::string print_depth_stencil_surface_format(surface_depth_format format) +std::string to_string(surface_depth_format format) { switch (format) { @@ -1115,7 +1115,7 @@ std::string print_depth_stencil_surface_format(surface_depth_format format) throw; } -std::string print_surface_antialiasing(surface_antialiasing format) +std::string to_string(surface_antialiasing format) { switch (format) { @@ -1127,7 +1127,7 @@ std::string print_surface_antialiasing(surface_antialiasing format) throw; } -std::string print_surface_color_format(surface_color_format format) +std::string to_string(surface_color_format format) { switch (format) { @@ -1149,7 +1149,7 @@ std::string print_surface_color_format(surface_color_format format) throw; } -std::string print_index_type(index_array_type arg) +std::string to_string(index_array_type arg) { switch (arg) { @@ -1159,7 +1159,7 @@ std::string print_index_type(index_array_type arg) throw; } -std::string print_context_dma(blit_engine::context_dma op) +std::string to_string(blit_engine::context_dma op) { switch (op) { @@ -1169,7 +1169,7 @@ std::string print_context_dma(blit_engine::context_dma op) throw; } -std::string print_transfer_origin(blit_engine::transfer_origin op) +std::string to_string(blit_engine::transfer_origin op) { switch (op) { @@ -1179,7 +1179,7 @@ std::string print_transfer_origin(blit_engine::transfer_origin op) throw; } -std::string print_transfer_interpolator(blit_engine::transfer_interpolator op) +std::string to_string(blit_engine::transfer_interpolator op) { switch (op) { @@ -1189,7 +1189,7 @@ std::string print_transfer_interpolator(blit_engine::transfer_interpolator op) throw; } -std::string print_shading_mode(shading_mode op) +std::string to_string(shading_mode op) { switch (op) { @@ -1199,7 +1199,7 @@ std::string print_shading_mode(shading_mode op) throw; } -std::string print_polygon_mode(polygon_mode op) +std::string to_string(polygon_mode op) { switch (op) { @@ -1999,10 +1999,17 @@ namespace namespace { + template + auto register_pretty_printing(u32 arg) + { + typename rsx::registers_decoder::decoded_type decoded_value(arg); + return rsx::registers_decoder::dump(std::move(arg)); + } + template auto create_printing_table(const std::integer_sequence &) { - return std::unordered_map{ {opcode, rsx::print_register_value}... }; + return std::unordered_map{ {opcode, register_pretty_printing}... }; } } diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index 71c65fd111..77843af698 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -11,10 +11,8 @@ namespace rsx } - void texture::init(u8 index) + void texture::init() { - m_index = index; - // Offset registers[NV4097_SET_TEXTURE_OFFSET + (m_index * 8)] = 0; @@ -255,10 +253,8 @@ namespace rsx } - void vertex_texture::init(u8 index) + void vertex_texture::init() { - m_index = index; - // Offset registers[NV4097_SET_VERTEX_TEXTURE_OFFSET + (m_index * 8)] = 0; diff --git a/rpcs3/Emu/RSX/RSXTexture.h b/rpcs3/Emu/RSX/RSXTexture.h index 2274832e7b..cb1f15e149 100644 --- a/rpcs3/Emu/RSX/RSXTexture.h +++ b/rpcs3/Emu/RSX/RSXTexture.h @@ -17,7 +17,7 @@ namespace rsx class texture { protected: - u8 m_index; + const u8 m_index; std::array ®isters; public: @@ -25,7 +25,7 @@ namespace rsx texture() = delete; //initialize texture registers with default values - void init(u8 index); + void init(); // Offset u32 offset() const; @@ -93,7 +93,7 @@ namespace rsx class vertex_texture { protected: - u8 m_index; + const u8 m_index; std::array ®isters; public: @@ -101,7 +101,7 @@ namespace rsx vertex_texture() = delete; //initialize texture registers with default values - void init(u8 index); + void init(); // Offset u32 offset() const; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index ab094404bd..c943364e70 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -477,9 +477,10 @@ namespace rsx frame_debug.command_queue.push_back(std::make_pair(reg, value)); } - if (auto method = methods[reg]) + const auto& It = methods.find(reg); + if (It != methods.end()) { - method(this, value); + It->second(this, value); } } diff --git a/rpcs3/Emu/RSX/rsx_decode.h b/rpcs3/Emu/RSX/rsx_decode.h index aafc5606fb..1832a81c15 100644 --- a/rpcs3/Emu/RSX/rsx_decode.h +++ b/rpcs3/Emu/RSX/rsx_decode.h @@ -1,83 +1,12 @@ #pragma once #include "Utilities/types.h" +#include "Utilities/BitField.h" #include #include "GCM.h" -#include "rsx_methods.h" #pragma warning(disable:4503) namespace { - struct split_reg_half_uint_decode - { - static std::tuple decode(u32 reg) - { - return std::make_tuple(reg & 0xffff, reg >> 16); - } - }; - - template - struct as_u16x2 - { - static std::tuple decode(u32 reg) - { - return std::make_tuple(reg & 0xffff, reg >> 16); - } - - static void commit_rsx_state(rsx::rsx_state &state, std::tuple &&decoded_values) - { - state.*FirstMember = std::get<0>(decoded_values); - state.*SecondMember = std::get<1>(decoded_values); - } - }; - - template - struct as_f32 - { - static f32 decode(u32 reg) - { - return reinterpret_cast(reg); - } - - static void commit_rsx_state(rsx::rsx_state &state, f32 &&decoded_values) - { - state.*Member = decoded_values; - } - }; - - - template - struct as_u32 - { - static u32 decode(u32 reg) - { - return reg; - } - - static void commit_rsx_state(rsx::rsx_state &state, u32 &&decoded_values) - { - state.*Member = decoded_values; - } - }; - - struct as_bool - { - static bool decode(u32 reg) - { - return !!reg; - } - }; - - struct as_unused - { - static u32 decode(u32 reg) { return reg; } - static void commit_rsx_state(rsx::rsx_state &state, u32 &&) {} - }; - - std::tuple split_reg_quad_uchar(u32 reg) - { - return std::make_tuple(reg & 0xff, (reg >> 8) & 0xff, (reg >> 16) & 0xff, (reg >> 24) & 0xff); - } - std::string get_subreg_name(u8 subreg) { return subreg == 0 ? "x" : @@ -105,219 +34,573 @@ namespace namespace rsx { std::string print_boolean(bool b); - std::string print_comparison_function(comparison_function f); - std::string print_stencil_op(stencil_op op); - std::string print_fog_mode(fog_mode op); - std::string print_logic_op(logic_op op); - std::string print_front_face(front_face op); - std::string print_cull_face(cull_face op); - std::string print_surface_target(surface_target target); - std::string print_primitive_mode(primitive_type draw_mode); - std::string print_transfer_operation(blit_engine::transfer_operation op); - std::string print_transfer_source_format(blit_engine::transfer_source_format op); - std::string print_context_surface(blit_engine::context_surface op); - std::string print_transfer_destination_format(blit_engine::transfer_destination_format op); - std::string print_blend_op(blend_equation op); - std::string print_blend_factor(blend_factor factor); - std::string print_origin_mode(window_origin origin); - std::string print_pixel_center_mode(window_pixel_center in); - std::string print_user_clip_plane_op(user_clip_plane_op op); - std::string print_depth_stencil_surface_format(surface_depth_format format); - std::string print_surface_antialiasing(surface_antialiasing format); - std::string print_surface_color_format(surface_color_format format); - std::string print_index_type(index_array_type arg); - std::string print_context_dma(blit_engine::context_dma op); - std::string print_transfer_origin(blit_engine::transfer_origin op); - std::string print_transfer_interpolator(blit_engine::transfer_interpolator op); - std::string print_shading_mode(shading_mode op); - std::string print_polygon_mode(polygon_mode op); + std::string to_string(comparison_function f); + std::string to_string(stencil_op op); + std::string to_string(fog_mode op); + std::string to_string(logic_op op); + std::string to_string(front_face op); + std::string to_string(cull_face op); + std::string to_string(surface_target target); + std::string to_string(primitive_type draw_mode); + std::string to_string(blit_engine::transfer_operation op); + std::string to_string(blit_engine::transfer_source_format op); + std::string to_string(blit_engine::context_surface op); + std::string to_string(blit_engine::transfer_destination_format op); + std::string to_string(blend_equation op); + std::string to_string(blend_factor factor); + std::string to_string(window_origin origin); + std::string to_string(window_pixel_center in); + std::string to_string(user_clip_plane_op op); + std::string to_string(surface_depth_format format); + std::string to_string(surface_antialiasing format); + std::string to_string(surface_color_format format); + std::string to_string(index_array_type arg); + std::string to_string(blit_engine::context_dma op); + std::string to_string(blit_engine::transfer_origin op); + std::string to_string(blit_engine::transfer_interpolator op); + std::string to_string(shading_mode op); + std::string to_string(polygon_mode op); template struct registers_decoder {}; -template -void commit(rsx_state &state, u32 value) -{ - registers_decoder::commit_rsx_state(state, registers_decoder::decode(value)); -} - -template -std::string print_register_value(u32 value) -{ - return registers_decoder::dump(registers_decoder::decode(value)); -} +template +using bitfield_decoder_t = bf_t; template<> -struct registers_decoder : - public as_u16x2<&rsx_state::m_viewport_origin_x, &rsx_state::m_viewport_width> +struct registers_decoder { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Viewport: x = " + std::to_string(std::get<0>(decoded_values)) + " width = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> origin_x; + bitfield_decoder_t<16, 16> width; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 origin_x() const + { + return m_data.origin_x; + } + + u16 width() const + { + return m_data.width; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Viewport: x = " + std::to_string(decoded_values.origin_x()) + " width = " + std::to_string(decoded_values.width()); } }; template<> struct registers_decoder - : public as_u16x2<&rsx_state::m_viewport_origin_y, &rsx_state::m_viewport_height> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Viewport: y = " + std::to_string(std::get<0>(decoded_values)) + " height = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> origin_y; + bitfield_decoder_t<16, 16> height; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 origin_y() const + { + return m_data.origin_y; + } + + u16 height() const + { + return m_data.height; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Viewport: y = " + std::to_string(decoded_values.origin_y()) + " height = " + std::to_string(decoded_values.height()); } }; template<> struct registers_decoder - : public as_u16x2<&rsx_state::m_scissor_origin_x, &rsx_state::m_scissor_width> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Scissor: x = " + std::to_string(std::get<0>(decoded_values)) + " width = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> origin_x; + bitfield_decoder_t<16, 16> width; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 origin_x() const + { + return m_data.origin_x; + } + + u16 width() const + { + return m_data.width; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Scissor: x = " + std::to_string(decoded_values.origin_x()) + " width = " + std::to_string(decoded_values.width()); } }; template<> struct registers_decoder - : public as_u16x2<&rsx_state::m_scissor_origin_y, &rsx_state::m_scissor_height> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Scissor: y = " + std::to_string(std::get<0>(decoded_values)) + " height = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> origin_y; + bitfield_decoder_t<16, 16> height; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 origin_y() const + { + return m_data.origin_y; + } + + u16 height() const + { + return m_data.height; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Scissor: y = " + std::to_string(decoded_values.origin_y()) + " height = " + std::to_string(decoded_values.height()); } }; template<> struct registers_decoder - : public as_u16x2<&rsx_state::m_surface_clip_origin_x, &rsx_state::m_surface_clip_width> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Surface: clip x = " + std::to_string(std::get<0>(decoded_values)) + " width = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> origin_x; + bitfield_decoder_t<16, 16> width; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 origin_x() const + { + return m_data.origin_x; + } + + u16 width() const + { + return m_data.width; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Surface: clip x = " + std::to_string(decoded_values.origin_x()) + " width = " + std::to_string(decoded_values.width()); } }; template<> struct registers_decoder< NV4097_SET_SURFACE_CLIP_VERTICAL> - : public as_u16x2<&rsx_state::m_surface_clip_origin_y, &rsx_state::m_surface_clip_height> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Surface: clip y = " + std::to_string(std::get<0>(decoded_values)) + " height = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> origin_y; + bitfield_decoder_t<16, 16> height; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 origin_y() const + { + return m_data.origin_y; + } + + u16 height() const + { + return m_data.height; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Surface: clip y = " + std::to_string(decoded_values.origin_y()) + " height = " + std::to_string(decoded_values.height()); } }; template<> struct registers_decoder - : public as_u16x2<&rsx_state::m_clear_rect_origin_x, &rsx_state::m_clear_rect_width> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Clear: rect x = " + std::to_string(std::get<0>(decoded_values)) + " width = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> origin_x; + bitfield_decoder_t<16, 16> width; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 origin_x() const + { + return m_data.origin_x; + } + + u16 width() const + { + return m_data.width; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Clear: rect x = " + std::to_string(decoded_values.origin_x()) + " width = " + std::to_string(decoded_values.width()); } }; template<> struct registers_decoder - : public as_u16x2<&rsx_state::m_clear_rect_origin_y, &rsx_state::m_clear_rect_height> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Clear: rect y = " + std::to_string(std::get<0>(decoded_values)) + " height = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> origin_y; + bitfield_decoder_t<16, 16> height; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 origin_y() const + { + return m_data.origin_y; + } + + u16 height() const + { + return m_data.height; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Clear: rect y = " + std::to_string(decoded_values.origin_y()) + " height = " + std::to_string(decoded_values.height()); } }; template<> struct registers_decoder< NV3089_CLIP_POINT> - : public as_u16x2<&rsx_state::m_blit_engine_clip_x, &rsx_state::m_blit_engine_clip_y> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Blit engine: clip x = " + std::to_string(std::get<0>(decoded_values)) + " y = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> clip_x; + bitfield_decoder_t<16, 16> clip_y; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 clip_x() const + { + return m_data.clip_x; + } + + u16 clip_y() const + { + return m_data.clip_y; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Blit engine: clip x = " + std::to_string(decoded_values.clip_x()) + " y = " + std::to_string(decoded_values.clip_y()); } }; template<> struct registers_decoder - : public as_u16x2<&rsx_state::m_blit_engine_width, &rsx_state::m_blit_engine_height> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Blit engine: clip width = " + std::to_string(std::get<0>(decoded_values)) + " height = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> width; + bitfield_decoder_t<16, 16> height; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 clip_width() const + { + return m_data.width; + } + + u16 clip_height() const + { + return m_data.height; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Blit engine: clip width = " + std::to_string(decoded_values.clip_width()) + " height = " + std::to_string(decoded_values.clip_height()); } }; template<> struct registers_decoder - : public as_u16x2<&rsx_state::m_blit_engine_output_x, &rsx_state::m_blit_engine_output_y> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Blit engine: output x = " + std::to_string(std::get<0>(decoded_values)) + " y = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> x; + bitfield_decoder_t<16, 16> y; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 x() const + { + return m_data.x; + } + + u16 y() const + { + return m_data.y; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Blit engine: output x = " + std::to_string(decoded_values.x()) + " y = " + std::to_string(decoded_values.y()); } }; template<> struct registers_decoder - : public as_u16x2<&rsx_state::m_shader_window_offset_x, &rsx_state::m_shader_window_offset_y> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Window: offset x = " + std::to_string(std::get<0>(decoded_values)) + " y = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> window_offset_x; + bitfield_decoder_t<16, 16> window_offset_y; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 window_offset_x() const + { + return m_data.window_offset_x; + } + + u16 window_offset_y() const + { + return m_data.window_offset_y; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Window: offset x = " + std::to_string(decoded_values.window_offset_x()) + " y = " + std::to_string(decoded_values.window_offset_y()); } }; template<> struct registers_decoder - : public as_u16x2<&rsx_state::m_blit_engine_output_width, &rsx_state::m_blit_engine_output_height> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Blit engine: output width = " + std::to_string(std::get<0>(decoded_values)) + " height = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> width; + bitfield_decoder_t<16, 16> height; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 width() const + { + return m_data.width; + } + + u16 height() const + { + return m_data.height; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Blit engine: output width = " + std::to_string(decoded_values.width()) + " height = " + std::to_string(decoded_values.height()); } }; template<> struct registers_decoder - : public as_u16x2<&rsx_state::m_blit_engine_input_width, &rsx_state::m_blit_engine_input_height> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Blit engine: input width = " + std::to_string(std::get<0>(decoded_values)) + " height = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> width; + bitfield_decoder_t<16, 16> height; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 width() const + { + return m_data.width; + } + + u16 height() const + { + return m_data.height; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Blit engine: input width = " + std::to_string(decoded_values.width()) + " height = " + std::to_string(decoded_values.height()); } }; template<> struct registers_decoder - : public as_u16x2<&rsx_state::m_blit_engine_output_alignement_nv3062, &rsx_state::m_blit_engine_output_pitch_nv3062> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Blit engine: output alignment = " + std::to_string(std::get<0>(decoded_values)) + " pitch = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> alignment; + bitfield_decoder_t<16, 16> pitch; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 alignment() const + { + return m_data.alignment; + } + + u16 pitch() const + { + return m_data.pitch; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Blit engine: output alignment = " + std::to_string(decoded_values.alignment()) + " pitch = " + std::to_string(decoded_values.pitch()); } }; template<> struct registers_decoder< NV308A_POINT> - : public as_u16x2<&rsx_state::m_nv308a_x, &rsx_state::m_nv308a_y> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "NV308A: x = " + std::to_string(std::get<0>(decoded_values)) + " y = " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> x; + bitfield_decoder_t<16, 16> y; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 x() const + { + return m_data.x; + } + + u16 y() const + { + return m_data.y; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "NV308A: x = " + std::to_string(decoded_values.x()) + " y = " + std::to_string(decoded_values.y()); } }; template<> -struct registers_decoder : public split_reg_half_uint_decode +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - std::tie(state.m_vertex_attrib_input_mask, std::ignore) = decoded_values; - } + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(std::tuple &&decoded_values) + u32 mask() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) { std::string result = "Transform program enabled inputs:"; const std::string input_names[] = @@ -330,544 +613,1194 @@ struct registers_decoder : public split_reg "in_tc4", "in_tc5", "in_tc6", "in_tc7" }; for (unsigned i = 0; i < 16; i++) - if (std::get<0>(decoded_values) & (1 << i)) + if (decoded_values.mask() & (1 << i)) result += input_names[i] + " "; - return result + " ? = " + std::to_string(std::get<1>(decoded_values)); + return result; } }; template<> -struct registers_decoder : public split_reg_half_uint_decode +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - std::tie(state.m_frequency_divider_operation_mask, std::ignore) = decoded_values; - } + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(std::tuple &&decoded_values) + u32 frequency_divider_operation_mask() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) { std::string result = "Frequency divider: "; for (unsigned i = 0; i < 16; i++) - if (std::get<0>(decoded_values) & (1 << i)) + if (decoded_values.frequency_divider_operation_mask() & (1 << i)) result += std::to_string(i) + " "; - return result + " ? = " + std::to_string(std::get<1>(decoded_values)); + return result; } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_depth_test_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> depth_test_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool depth_test_enabled() const + { + return bool(m_data.depth_test_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Depth: test " + print_boolean(decoded_values); + return "Depth: test " + print_boolean(decoded_values.depth_test_enabled()); } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_depth_write_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> depth_write_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool depth_write_enabled() const + { + return bool(m_data.depth_write_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Depth: write " + print_boolean(decoded_values); - } -}; - - -template<> -struct registers_decoder : public as_bool -{ - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) - { - state.m_alpha_test_enabled = decoded_values; - } - - static std::string dump(bool &&decoded_values) - { - return "Alpha: test " + print_boolean(decoded_values); + return "Depth: write " + print_boolean(decoded_values.depth_write_enabled()); } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_stencil_test_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> alpha_test_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool alpha_test_enabled() const + { + return bool(m_data.alpha_test_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Stencil: test " + print_boolean(decoded_values); + return "Alpha: test " + print_boolean(decoded_values.alpha_test_enabled()); } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_restart_index_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> stencil_test_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool stencil_test_enabled() const + { + return bool(m_data.stencil_test_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Restart Index: " + print_boolean(decoded_values); + return "Stencil: test " + print_boolean(decoded_values.stencil_test_enabled()); } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_depth_bounds_test_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> restart_index_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool restart_index_enabled() const + { + return bool(m_data.restart_index_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Depth: bound test " + print_boolean(decoded_values); + return "Restart Index: " + print_boolean(decoded_values.restart_index_enabled()); } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_logic_op_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> depth_bound_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool depth_bound_enabled() const + { + return bool(m_data.depth_bound_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Logic: " + print_boolean(decoded_values); + return "Depth: bound test " + print_boolean(decoded_values.depth_bound_enabled()); } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_dither_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> logic_op_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool logic_op_enabled() const + { + return bool(m_data.logic_op_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Dither: " + print_boolean(decoded_values); + return "Logic: " + print_boolean(decoded_values.logic_op_enabled()); } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_blend_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> dither_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool dither_enabled() const + { + return bool(m_data.dither_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Blend: " + print_boolean(decoded_values); + return "Dither: " + print_boolean(decoded_values.dither_enabled()); } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_line_smooth_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> blend_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool blend_enabled() const + { + return bool(m_data.blend_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Line: smooth " + print_boolean(decoded_values); + return "Blend: " + print_boolean(decoded_values.blend_enabled()); } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_poly_offset_point_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> line_smooth_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool line_smooth_enabled() const + { + return bool(m_data.line_smooth_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Polygon: offset point " + print_boolean(decoded_values); + return "Line: smooth " + print_boolean(decoded_values.line_smooth_enabled()); } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_offset_line_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> poly_offset_point_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool poly_offset_point_enabled() const + { + return bool(m_data.poly_offset_point_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Polygon: offset line " + print_boolean(decoded_values); + return "Polygon: offset point " + print_boolean(decoded_values.poly_offset_point_enabled()); } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_poly_offset_fill_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> poly_offset_line_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool poly_offset_line_enabled() const + { + return bool(m_data.poly_offset_line_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Polygon: offset fill " + print_boolean(decoded_values); + return "Polygon: offset line " + print_boolean(decoded_values.poly_offset_line_enabled()); } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_cull_face_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> poly_offset_fill_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool poly_offset_fill_enabled() const + { + return bool(m_data.poly_offset_fill_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Cull face: " + print_boolean(decoded_values); + return "Polygon: offset fill " + print_boolean(decoded_values.poly_offset_fill_enabled()); } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_poly_smooth_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> cull_face_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool cull_face_enabled() const + { + return bool(m_data.cull_face_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Polygon: smooth " + print_boolean(decoded_values); + return "Cull face: " + print_boolean(decoded_values.cull_face_enabled()); } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_two_sided_stencil_test_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> poly_smooth_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool poly_smooth_enabled() const + { + return bool(m_data.poly_smooth_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Stencil: per side " + print_boolean(decoded_values); + return "Polygon: smooth " + print_boolean(decoded_values.poly_smooth_enabled()); } }; template<> -struct registers_decoder : public as_bool +struct registers_decoder { - static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + struct decoded_type { - state.m_two_side_light_enabled = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> two_sided_stencil_test_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(bool &&decoded_values) + bool two_sided_stencil_test_enabled() const + { + return bool(m_data.two_sided_stencil_test_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Light: per side " + print_boolean(decoded_values); + return "Stencil: per side " + print_boolean(decoded_values.two_sided_stencil_test_enabled()); + } +}; + +template<> +struct registers_decoder +{ + struct decoded_type + { + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> two_sided_lighting_enabled; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + bool two_sided_lighting_enabled() const + { + return bool(m_data.two_sided_lighting_enabled); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Light: per side " + print_boolean(decoded_values.two_sided_lighting_enabled()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_depth_bounds_min> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Depth: bound min = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> depth_bound_min; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 depth_bound_min() const + { + return reinterpret_cast(m_data.depth_bound_min); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Depth: bound min = " + std::to_string(decoded_values.depth_bound_min()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_depth_bounds_max> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Depth: bound max = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> depth_bound_max; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 depth_bound_max() const + { + return reinterpret_cast(m_data.depth_bound_max); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Depth: bound max = " + std::to_string(decoded_values.depth_bound_max()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_fog_params_0> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Fog: param 0 = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> fog_param_0; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 fog_param_0() const + { + return reinterpret_cast(m_data.fog_param_0); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Fog: param 0 = " + std::to_string(decoded_values.fog_param_0()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_fog_params_1> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Fog: param 1 = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> fog_param_1; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 fog_param_1() const + { + return reinterpret_cast(m_data.fog_param_1); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Fog: param 1 = " + std::to_string(decoded_values.fog_param_1()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_clip_min> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Depth: clip min = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> clip_min; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 clip_min() const + { + return reinterpret_cast(m_data.clip_min); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Depth: clip min = " + std::to_string(decoded_values.clip_min()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_clip_max> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Depth: clip max = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> clip_max; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 clip_max() const + { + return reinterpret_cast(m_data.clip_max); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Depth: clip max = " + std::to_string(decoded_values.clip_max()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_poly_offset_scale> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Polygon: offset scale = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> polygon_offset_scale_factor; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 polygon_offset_scale_factor() const + { + return reinterpret_cast(m_data.polygon_offset_scale_factor); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Polygon: offset scale = " + std::to_string(decoded_values.polygon_offset_scale_factor()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_poly_offset_bias> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Polygon: offset bias = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> polygon_offset_scale_bias; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 polygon_offset_scale_bias() const + { + return reinterpret_cast(m_data.polygon_offset_scale_bias); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Polygon: offset bias = " + std::to_string(decoded_values.polygon_offset_scale_bias()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_viewport_scale_x> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Viewport: scale x = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> viewport_scale_x; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 viewport_scale_x() const + { + return reinterpret_cast(m_data.viewport_scale_x); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Viewport: scale x = " + std::to_string(decoded_values.viewport_scale_x()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_viewport_scale_y> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Viewport: scale y = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> viewport_scale_y; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 viewport_scale_y() const + { + return reinterpret_cast(m_data.viewport_scale_y); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Viewport: scale y = " + std::to_string(decoded_values.viewport_scale_y()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_viewport_scale_z> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Viewport: scale z = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> viewport_scale_z; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 viewport_scale_z() const + { + return reinterpret_cast(m_data.viewport_scale_z); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Viewport: scale z = " + std::to_string(decoded_values.viewport_scale_z()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_viewport_scale_w> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Viewport: scale w = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> viewport_scale_w; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 viewport_scale_w() const + { + return reinterpret_cast(m_data.viewport_scale_w); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Viewport: scale w = " + std::to_string(decoded_values.viewport_scale_w()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_viewport_offset_x> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Viewport: offset x = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> viewport_offset_x; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 viewport_offset_x() const + { + return reinterpret_cast(m_data.viewport_offset_x); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Viewport: offset x = " + std::to_string(decoded_values.viewport_offset_x()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_viewport_offset_y> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Viewport: offset y = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> viewport_offset_y; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 viewport_offset_y() const + { + return reinterpret_cast(m_data.viewport_offset_y); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Viewport: offset y = " + std::to_string(decoded_values.viewport_offset_y()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_viewport_offset_z> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Viewport: offset z = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> viewport_offset_z; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 viewport_offset_z() const + { + return reinterpret_cast(m_data.viewport_offset_z); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Viewport: offset z = " + std::to_string(decoded_values.viewport_offset_z()); } }; template<> struct registers_decoder - : as_f32<&rsx_state::m_viewport_offset_w> { - static std::string dump(f32 &&decoded_values) + struct decoded_type { - return "Viewport: offset w = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> viewport_offset_w; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 viewport_offset_w() const + { + return reinterpret_cast(m_data.viewport_offset_w); + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Viewport: offset w = " + std::to_string(decoded_values.viewport_offset_w()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_restart_index> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Restart index: " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 restart_index() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Restart index: " + std::to_string(decoded_values.restart_index()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_surface_a_offset> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Surface: A offset " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 surface_a_offset() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Surface: A offset " + std::to_string(decoded_values.surface_a_offset()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_surface_b_offset> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Surface: B offset " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 surface_b_offset() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Surface: B offset " + std::to_string(decoded_values.surface_b_offset()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_surface_c_offset> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Surface: C offset " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 surface_c_offset() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Surface: C offset " + std::to_string(decoded_values.surface_c_offset()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_surface_d_offset> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Surface: D offset " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 surface_d_offset() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Surface: D offset " + std::to_string(decoded_values.surface_d_offset()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_surface_a_pitch> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Surface: A pitch " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 surface_a_pitch() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Surface: A pitch " + std::to_string(decoded_values.surface_a_pitch()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_surface_b_pitch> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Surface: B pitch " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 surface_b_pitch() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Surface: B pitch " + std::to_string(decoded_values.surface_b_pitch()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_surface_c_pitch> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Surface: C pitch " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 surface_c_pitch() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Surface: C pitch " + std::to_string(decoded_values.surface_c_pitch()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_surface_d_pitch> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Surface: D pitch " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 surface_d_pitch() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Surface: D pitch " + std::to_string(decoded_values.surface_d_pitch()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_surface_z_offset> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Surface: Z offset " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 surface_z_offset() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Surface: Z offset " + std::to_string(decoded_values.surface_z_offset()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_surface_z_pitch> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Surface: Z pitch " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 surface_z_pitch() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Surface: Z pitch " + std::to_string(decoded_values.surface_z_pitch()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_vertex_attrib_output_mask> { - static std::string dump(u32 &&decoded_values) + struct decoded_type + { + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 output_mask() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) { const std::string output_names[] = { @@ -896,7 +1829,7 @@ struct registers_decoder }; std::string result = "Transform program outputs:"; for (unsigned i = 0; i < 22; i++) - if (decoded_values & (1 << i)) + if (decoded_values.output_mask() & (1 << i)) result += output_names[i] + " "; return result; } @@ -904,517 +1837,991 @@ struct registers_decoder template<> struct registers_decoder - : as_u32<&rsx_state::m_shader_control> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Shader control: raw_value =" + std::to_string(decoded_values) + - " reg_count = " + std::to_string((decoded_values >> 24) & 0xFF) + - ((decoded_values & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT) ? " depth_replace " : "") + - ((decoded_values & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS) ? " 32b_exports " : ""); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 shader_ctrl() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Shader control: raw_value =" + std::to_string(decoded_values.shader_ctrl()) + + " reg_count = " + std::to_string((decoded_values.shader_ctrl() >> 24) & 0xFF) + + ((decoded_values.shader_ctrl() & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT) ? " depth_replace " : "") + + ((decoded_values.shader_ctrl() & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS) ? " 32b_exports " : ""); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_vertex_data_base_offset> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Vertex: base offset " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 vertex_data_base_offset() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Vertex: base offset " + std::to_string(decoded_values.vertex_data_base_offset()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_index_array_address> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Index: array offset " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 index_array_offset() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Index: array offset " + std::to_string(decoded_values.index_array_offset()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_vertex_data_base_index> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Vertex: base index " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 vertex_data_base_index() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Vertex: base index " + std::to_string(decoded_values.vertex_data_base_index()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_shader_program_address> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Shader: program offset = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 shader_program_address() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Shader: program offset = " + std::to_string(decoded_values.shader_program_address()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_transform_program_start> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Transform program: start = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 transform_program_start() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Transform program: start = " + std::to_string(decoded_values.transform_program_start()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_semaphore_offset_406e> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "NV406E semaphore: offset = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 semaphore_offset() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "NV406E semaphore: offset = " + std::to_string(decoded_values.semaphore_offset()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_semaphore_offset_4097> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "semaphore: offset = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 semaphore_offset() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "semaphore: offset = " + std::to_string(decoded_values.semaphore_offset()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_blit_engine_input_offset> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "NV3089: input offset = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 input_offset() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "NV3089: input offset = " + std::to_string(decoded_values.input_offset()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_blit_engine_output_offset_nv3062> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "NV3062: output offset = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 output_offset() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "NV3062: output offset = " + std::to_string(decoded_values.output_offset()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_blit_engine_nv309E_offset> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "NV309E: offset = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 offset() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "NV309E: offset = " + std::to_string(decoded_values.offset()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_blit_engine_ds_dx> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "NV3089: dsdx = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 ds_dx() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "NV3089: dsdx = " + std::to_string(decoded_values.ds_dx()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_blit_engine_dt_dy> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "NV3089: dtdy = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 dt_dy() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "NV3089: dtdy = " + std::to_string(decoded_values.dt_dy()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_nv0039_input_pitch> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "NV0039: input pitch = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 input_pitch() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "NV0039: input pitch = " + std::to_string(decoded_values.input_pitch()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_nv0039_output_pitch> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "NV0039: output pitch = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 output_pitch() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "NV0039: output pitch = " + std::to_string(decoded_values.output_pitch()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_nv0039_line_length> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "NV0039: line lenght input = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 input_line_length() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "NV0039: line lenght input = " + std::to_string(decoded_values.input_line_length()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_nv0039_line_count> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "NV0039: line count = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 line_count() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "NV0039: line count = " + std::to_string(decoded_values.line_count()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_nv0039_output_offset> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "NV0039: output offset = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 output_offset() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "NV0039: output offset = " + std::to_string(decoded_values.output_offset()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_nv0039_input_offset> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "NV0039: input offset = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 input_offset() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "NV0039: input offset = " + std::to_string(decoded_values.input_offset()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return to_comparison_function(value); } - - static void commit_rsx_state(rsx_state &state, comparison_function &&decoded_values) + struct decoded_type { - state.m_depth_func = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> depth_func; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(comparison_function &&decoded_values) + rsx::comparison_function depth_func() const + { + return to_comparison_function(m_data.depth_func); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Depth: compare_function = " + print_comparison_function(decoded_values); + return "Depth: compare_function = " + to_string(decoded_values.depth_func()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return to_comparison_function(value); } - - static void commit_rsx_state(rsx_state &state, comparison_function &&decoded_values) + struct decoded_type { - state.m_stencil_func = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> stencil_func; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(comparison_function &&decoded_values) + rsx::comparison_function stencil_func() const + { + return to_comparison_function(m_data.stencil_func); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Stencil: (front) compare_function = " + print_comparison_function(decoded_values); + return "Stencil: (front) compare_function = " + to_string(decoded_values.stencil_func()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return to_comparison_function(value); } - - static void commit_rsx_state(rsx_state &state, comparison_function &&decoded_values) + struct decoded_type { - state.m_back_stencil_func = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> back_stencil_func; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(comparison_function &&decoded_values) + rsx::comparison_function back_stencil_func() const + { + return to_comparison_function(m_data.back_stencil_func); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Stencil: back compare_function = " + print_comparison_function(decoded_values); + return "Stencil: back compare_function = " + to_string(decoded_values.back_stencil_func()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return to_comparison_function(value); } - - static void commit_rsx_state(rsx_state &state, comparison_function &&decoded_values) + struct decoded_type { - state.m_alpha_func = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> alpha_func; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(comparison_function &&decoded_values) + rsx::comparison_function alpha_func() const + { + return to_comparison_function(m_data.alpha_func); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Alpha: compare_function = " + print_comparison_function(decoded_values); + return "Alpha: compare_function = " + to_string(decoded_values.alpha_func()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return to_stencil_op(value); } - - static void commit_rsx_state(rsx_state &state, stencil_op &&decoded_values) + struct decoded_type { - state.m_stencil_op_fail = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> fail; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(stencil_op &&decoded_values) + rsx::stencil_op fail() const + { + return to_stencil_op(m_data.fail); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Stencil: (front) fail op = " + print_stencil_op(decoded_values); + return "Stencil: (front) fail op = " + to_string(decoded_values.fail()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return to_stencil_op(value); } - - static void commit_rsx_state(rsx_state &state, stencil_op &&decoded_values) + struct decoded_type { - state.m_stencil_op_zfail = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> zfail; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(stencil_op &&decoded_values) + rsx::stencil_op zfail() const + { + return to_stencil_op(m_data.zfail); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Stencil: (front) zfail op = " + print_stencil_op(decoded_values); + return "Stencil: (front) zfail op = " + to_string(decoded_values.zfail()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return to_stencil_op(value); } - - static void commit_rsx_state(rsx_state &state, stencil_op &&decoded_values) + struct decoded_type { - state.m_stencil_op_zpass = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> zpass; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(stencil_op &&decoded_values) + rsx::stencil_op zpass() const + { + return to_stencil_op(m_data.zpass); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Stencil: (front) zpass op = " + print_stencil_op(decoded_values); + return "Stencil: (front) zpass op = " + to_string(decoded_values.zpass()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return to_stencil_op(value); } - - static void commit_rsx_state(rsx_state &state, stencil_op &&decoded_values) + struct decoded_type { - state.m_back_stencil_op_fail = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> back_fail; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(stencil_op &&decoded_values) + rsx::stencil_op back_fail() const + { + return to_stencil_op(m_data.back_fail); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Stencil: (back) fail op = " + print_stencil_op(decoded_values); + return "Stencil: (back) fail op = " + to_string(decoded_values.back_fail()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return to_stencil_op(value); } - - static void commit_rsx_state(rsx_state &state, stencil_op &&decoded_values) + struct decoded_type { - state.m_back_stencil_op_zfail = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> back_zfail; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(stencil_op &&decoded_values) + rsx::stencil_op back_zfail() const + { + return to_stencil_op(m_data.back_zfail); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Stencil: (back) zfail op = " + print_stencil_op(decoded_values); + return "Stencil: (back) zfail op = " + to_string(decoded_values.back_zfail()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return to_stencil_op(value); } - - static void commit_rsx_state(rsx_state &state, stencil_op &&decoded_values) + struct decoded_type { - state.m_back_stencil_op_zpass = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> back_zpass; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(stencil_op &&decoded_values) + rsx::stencil_op back_zpass() const + { + return to_stencil_op(m_data.back_zpass); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Stencil: (back) zpass op = " + print_stencil_op(decoded_values); + return "Stencil: (back) zpass op = " + to_string(decoded_values.back_zpass()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return split_reg_quad_uchar(value); } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_stencil_func_ref = std::get<0>(decoded_values); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 8> stencil_func_ref; + } m_data; - static std::string dump(std::tuple &&decoded_values) + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u8 stencil_func_ref() const { return m_data.stencil_func_ref; } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Stencil: (front) func ref = " + std::to_string(std::get<0>(decoded_values)); + return "Stencil: (front) func ref = " + std::to_string(decoded_values.stencil_func_ref()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return split_reg_quad_uchar(value); } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_back_stencil_func_ref = std::get<0>(decoded_values); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 8> back_stencil_func_ref; + } m_data; - static std::string dump(std::tuple &&decoded_values) + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u8 back_stencil_func_ref() const { return m_data.back_stencil_func_ref; } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Stencil: (back) func ref = " + std::to_string(std::get<0>(decoded_values)); + return "Stencil: (back) func ref = " + std::to_string(decoded_values.back_stencil_func_ref()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return split_reg_quad_uchar(value); } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_stencil_func_mask = std::get<0>(decoded_values); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 8> stencil_func_mask; + } m_data; - static std::string dump(std::tuple &&decoded_values) + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u8 stencil_func_mask() const { return m_data.stencil_func_mask; } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Stencil: (front) func mask = " + std::to_string(std::get<0>(decoded_values)); + return "Stencil: (front) func mask = " + std::to_string(decoded_values.stencil_func_mask()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return split_reg_quad_uchar(value); } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_back_stencil_func_mask = std::get<0>(decoded_values); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 8> back_stencil_func_mask; + } m_data; - static std::string dump(std::tuple &&decoded_values) + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u8 back_stencil_func_mask() const { return m_data.back_stencil_func_mask; } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Stencil: (back) func mask = " + std::to_string(std::get<0>(decoded_values)); + return "Stencil: (back) func mask = " + std::to_string(decoded_values.back_stencil_func_mask()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return split_reg_quad_uchar(value); } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_alpha_ref = std::get<0>(decoded_values); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 8> alpha_ref; + } m_data; - static std::string dump(std::tuple &&decoded_values) + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u8 alpha_ref() const { return m_data.alpha_ref; } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Alpha: ref = " + std::to_string(std::get<0>(decoded_values)); + return "Alpha: ref = " + std::to_string(decoded_values.alpha_ref()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return split_reg_quad_uchar(value); } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - std::tie(state.m_clear_color_b, state.m_clear_color_g, state.m_clear_color_r, state.m_clear_color_a) = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 8> red; + bitfield_decoder_t<8, 8> green; + bitfield_decoder_t<16, 8> blue; + bitfield_decoder_t<24, 8> alpha; + } m_data; - static std::string dump(std::tuple &&decoded_values) + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u8 red() const { return m_data.red; } + u8 green() const { return m_data.red; } + u8 blue() const { return m_data.red; } + u8 alpha() const { return m_data.red; } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Clear: R = " + std::to_string(std::get<0>(decoded_values)) + - " G = " + std::to_string(std::get<1>(decoded_values)) + - " B = " + std::to_string(std::get<2>(decoded_values)) + - " A = " + std::to_string(std::get<3>(decoded_values)); + return "Clear: R = " + std::to_string(decoded_values.red()) + + " G = " + std::to_string(decoded_values.green()) + + " B = " + std::to_string(decoded_values.blue()) + + " A = " + std::to_string(decoded_values.alpha()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return split_reg_quad_uchar(value); } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_stencil_mask = std::get<0>(decoded_values); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 8> stencil_mask; + } m_data; - static std::string dump(std::tuple &&decoded_values) + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u8 stencil_mask() const { return m_data.stencil_mask; } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Stencil: (front) mask = " + std::to_string(std::get<0>(decoded_values)); + return "Stencil: (front) mask = " + std::to_string(decoded_values.stencil_mask()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return split_reg_quad_uchar(value); } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_back_stencil_mask = std::get<0>(decoded_values); - } - - static std::string dump(std::tuple &&decoded_values) +private: + union { - return "Stencil: (back) mask = " + std::to_string(std::get<0>(decoded_values)); + u32 raw_value; + bitfield_decoder_t<0, 8> back_stencil_mask; + } m_data; +public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u8 back_stencil_mask() const { return m_data.back_stencil_mask; } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Stencil: (back) mask = " + std::to_string(decoded_values.back_stencil_mask()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return to_logic_op(value); } - - static void commit_rsx_state(rsx_state &state, logic_op &&decoded_values) + struct decoded_type { - state.m_logic_operation = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> logic_operation; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(logic_op &&decoded_values) + logic_op logic_operation() const + { + return to_logic_op(m_data.logic_operation); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Logic: op = " + print_logic_op(decoded_values); + return "Logic: op = " + to_string(decoded_values.logic_operation()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return to_front_face(value); } - - static void commit_rsx_state(rsx_state &state, front_face &&decoded_values) + struct decoded_type { - state.m_front_face_mode = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> front_face_mode; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(front_face &&decoded_values) + front_face front_face_mode() const + { + return to_front_face(m_data.front_face_mode); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Front Face: " + print_front_face(decoded_values); + return "Front Face: " + to_string(decoded_values.front_face_mode()); } }; @@ -1422,689 +2829,1179 @@ struct registers_decoder template<> struct registers_decoder { - static auto decode(u32 value) { return to_cull_face(value); } - - static void commit_rsx_state(rsx_state &state, cull_face &&decoded_values) + struct decoded_type { - state.m_cull_face_mode = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> cull_face_mode; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(cull_face &&decoded_values) + cull_face cull_face_mode() const + { + return to_cull_face(m_data.cull_face_mode); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Cull Face: " + print_cull_face(decoded_values); + return "Cull Face: " + to_string(decoded_values.cull_face_mode()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return to_surface_target(value); } - - static void commit_rsx_state(rsx_state &state, surface_target &&decoded_values) + struct decoded_type { - state.m_surface_color_target = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> target; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(surface_target &&decoded_values) + surface_target target() const + { + return to_surface_target(m_data.target); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Surface: Color target(s) = " + print_surface_target(decoded_values); + return "Surface: Color target(s) = " + to_string(decoded_values.target()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return to_fog_mode(value); } - - static void commit_rsx_state(rsx_state &state, fog_mode &&decoded_values) + struct decoded_type { - state.m_fog_equation = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> fog_equation; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(fog_mode &&decoded_values) + fog_mode fog_equation() const + { + return to_fog_mode(m_data.fog_equation); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Fog: " + print_fog_mode(decoded_values); + return "Fog: " + to_string(decoded_values.fog_equation()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return to_primitive_type(value); } - - static void commit_rsx_state(rsx_state &state, primitive_type &&decoded_values) + struct decoded_type { - state.m_primitive_type = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> primitive; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(primitive_type &&decoded_values) + primitive_type primitive() const + { + return to_primitive_type(m_data.primitive); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "-- " + print_primitive_mode(decoded_values) + " --"; + return "-- " + to_string(decoded_values.primitive()) + " --"; } }; template<> struct registers_decoder { - static auto decode(u32 value) { return blit_engine::to_transfer_operation(value); } - - static void commit_rsx_state(rsx_state &state, blit_engine::transfer_operation &&decoded_values) + struct decoded_type { - state.m_blit_engine_operation = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> transfer_op; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(blit_engine::transfer_operation &&decoded_values) + blit_engine::transfer_operation transfer_op() const + { + return blit_engine::to_transfer_operation(m_data.transfer_op); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "NV3089: op = " + print_transfer_operation(decoded_values); + return "NV3089: op = " + to_string(decoded_values.transfer_op()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return blit_engine::to_transfer_source_format(value); } - - static void commit_rsx_state(rsx_state &state, blit_engine::transfer_source_format &&decoded_values) + struct decoded_type { - state.m_blit_engine_src_color_format = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> transfer_source_fmt; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(blit_engine::transfer_source_format &&decoded_values) + blit_engine::transfer_source_format transfer_source_fmt() const + { + return blit_engine::to_transfer_source_format(m_data.transfer_source_fmt); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "NV3089: source fmt = " + print_transfer_source_format(decoded_values); + return "NV3089: source fmt = " + to_string(decoded_values.transfer_source_fmt()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return blit_engine::to_context_surface(value); } - - static void commit_rsx_state(rsx_state &state, blit_engine::context_surface &&decoded_values) + struct decoded_type { - state.m_blit_engine_context_surface = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> ctx_surface; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(blit_engine::context_surface &&decoded_values) + blit_engine::context_surface ctx_surface() const + { + return blit_engine::to_context_surface(m_data.ctx_surface); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "NV3089: context surface = " + print_context_surface(decoded_values); + return "NV3089: context surface = " + to_string(decoded_values.ctx_surface()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { return blit_engine::to_transfer_destination_format(value); } - - static void commit_rsx_state(rsx_state &state, blit_engine::transfer_destination_format &&decoded_values) + struct decoded_type { - state.m_blit_engine_nv3062_color_format = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> transfer_dest_fmt; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(blit_engine::transfer_destination_format &&decoded_values) + blit_engine::transfer_destination_format transfer_dest_fmt() const + { + return blit_engine::to_transfer_destination_format(m_data.transfer_dest_fmt); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "NV3062: output fmt = " + print_transfer_destination_format(decoded_values); + return "NV3062: output fmt = " + to_string(decoded_values.transfer_dest_fmt()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - auto tmp = split_reg_half_uint_decode::decode(value); - return std::make_tuple(to_blend_equation(std::get<0>(tmp)), to_blend_equation(std::get<1>(tmp))); - } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_blend_equation_rgb = std::get<0>(decoded_values); - state.m_blend_equation_a = std::get<1>(decoded_values); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> blend_rgb; + bitfield_decoder_t<16, 16> blend_a; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(std::tuple &&decoded_values) + blend_equation blend_rgb() const + { + return to_blend_equation(m_data.blend_rgb); + } + + blend_equation blend_a() const + { + return to_blend_equation(m_data.blend_a); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Blend: equation rgb = " + print_blend_op(std::get<0>(decoded_values)) + " a = " + print_blend_op(std::get<1>(decoded_values)); + return "Blend: equation rgb = " + to_string(decoded_values.blend_rgb()) + + " a = " + to_string(decoded_values.blend_a()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - auto tmp = split_reg_half_uint_decode::decode(value); - return std::make_tuple(to_blend_factor(std::get<0>(tmp)), to_blend_factor(std::get<1>(tmp))); - } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_blend_func_sfactor_rgb = std::get<0>(decoded_values); - state.m_blend_func_sfactor_a = std::get<1>(decoded_values); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> src_blend_rgb; + bitfield_decoder_t<16, 16> src_blend_a; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(std::tuple &&decoded_values) + blend_factor src_blend_rgb() const + { + return to_blend_factor(m_data.src_blend_rgb); + } + + blend_factor src_blend_a() const + { + return to_blend_factor(m_data.src_blend_a); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Blend: sfactor rgb = " + print_blend_factor(std::get<0>(decoded_values)) + " a = " + print_blend_factor(std::get<1>(decoded_values)); + return "Blend: sfactor rgb = " + to_string(decoded_values.src_blend_rgb()) + + " a = " + to_string(decoded_values.src_blend_a()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - auto tmp = split_reg_half_uint_decode::decode(value); - return std::make_tuple(to_blend_factor(std::get<0>(tmp)), to_blend_factor(std::get<1>(tmp))); - } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_blend_func_dfactor_rgb = std::get<0>(decoded_values); - state.m_blend_func_dfactor_a = std::get<1>(decoded_values); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> dst_blend_rgb; + bitfield_decoder_t<16, 16> dst_blend_a; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(std::tuple &&decoded_values) + blend_factor dst_blend_rgb() const + { + return to_blend_factor(m_data.dst_blend_rgb); + } + + blend_factor dst_blend_a() const + { + return to_blend_factor(m_data.dst_blend_a); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Blend: dfactor rgb = " + print_blend_factor(std::get<0>(decoded_values)) + " a = " + print_blend_factor(std::get<1>(decoded_values)); + return "Blend: dfactor rgb = " + to_string(decoded_values.dst_blend_rgb()) + + " a = " + to_string(decoded_values.dst_blend_a()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - auto tmp = split_reg_quad_uchar(value); - return std::make_tuple(!!std::get<0>(tmp), !!std::get<1>(tmp), !!std::get<2>(tmp), !!std::get<3>(tmp)); - } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_color_mask_b = std::get<0>(decoded_values); - state.m_color_mask_g = std::get<1>(decoded_values); - state.m_color_mask_r = std::get<2>(decoded_values); - state.m_color_mask_a = std::get<3>(decoded_values); - } + private: + union + { + u32 raw_data; + bitfield_decoder_t<0, 8> color_b; + bitfield_decoder_t<8, 8> color_g; + bitfield_decoder_t<16, 8> color_r; + bitfield_decoder_t<24, 8> color_a; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_data = raw_value; } - static std::string dump(std::tuple &&decoded_values) + bool color_b() const + { + return bool(m_data.color_b); + } + + bool color_g() const + { + return bool(m_data.color_g); + } + + bool color_r() const + { + return bool(m_data.color_r); + } + + bool color_a() const + { + return bool(m_data.color_a); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Surface: color mask A = " + print_boolean(std::get<3>(decoded_values)) + - " R = " + print_boolean(std::get<2>(decoded_values)) + - " G = " + print_boolean(std::get<1>(decoded_values)) + - " B = " + print_boolean(std::get<0>(decoded_values)); + return "Surface: color mask A = " + print_boolean(decoded_values.color_a()) + + " R = " + print_boolean(decoded_values.color_r()) + + " G = " + print_boolean(decoded_values.color_g()) + + " B = " + print_boolean(decoded_values.color_b()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return std::make_tuple( - to_window_origin((value >> 12) & 0xf), - to_window_pixel_center((value >> 16) & 0xf), - static_cast(value & 0xfff) - ); - } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_shader_window_origin = std::get<0>(decoded_values); - state.m_shader_window_pixel = std::get<1>(decoded_values); - state.m_shader_window_height = std::get<2>(decoded_values); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 12> window_shader_height; + bitfield_decoder_t<12, 4> window_shader_origin; + bitfield_decoder_t<16, 4> window_shader_pixel_center; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(std::tuple &&decoded_values) + window_origin window_shader_origin() const + { + return to_window_origin(m_data.window_shader_origin); + } + + window_pixel_center window_shader_pixel_center() const + { + return to_window_pixel_center(m_data.window_shader_pixel_center); + } + + u16 window_shader_height() const + { + return m_data.window_shader_height; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Viewport: height = " + std::to_string(std::get<2>(decoded_values)) + - " origin = " + print_origin_mode(std::get<0>(decoded_values)) + - " pixel center = " + print_pixel_center_mode(std::get<1>(decoded_values)); + return "Viewport: height = " + std::to_string(decoded_values.window_shader_height()) + + " origin = " + to_string(decoded_values.window_shader_origin()) + + " pixel center = " + to_string(decoded_values.window_shader_pixel_center()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return std::make_tuple( - !!(value & 0x2), - !!(value & 0x4), - !!(value & 0x8) - ); - } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_blend_enabled_surface_1 = std::get<0>(decoded_values); - state.m_blend_enabled_surface_2 = std::get<1>(decoded_values); - state.m_blend_enabled_surface_3 = std::get<2>(decoded_values); - } + private: + union + { + u32 raw_data; + bitfield_decoder_t<1, 1> blend_surface_b; + bitfield_decoder_t<2, 1> blend_surface_c; + bitfield_decoder_t<3, 1> blend_surface_d; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_data = raw_value; } - static std::string dump(std::tuple&& decoded_values) + bool blend_surface_b() const + { + return bool(m_data.blend_surface_b); + } + + bool blend_surface_c() const + { + return bool(m_data.blend_surface_c); + } + + bool blend_surface_d() const + { + return bool(m_data.blend_surface_d); + } + }; + + static std::string dump(decoded_type&& decoded_values) { - return "Blend: mrt1 = " + print_boolean(std::get<0>(decoded_values)) + - " mrt2 = " + print_boolean(std::get<1>(decoded_values)) + - " mrt3 = " + print_boolean(std::get<2>(decoded_values)); + return "Blend: mrt1 = " + print_boolean(decoded_values.blend_surface_b()) + + " mrt2 = " + print_boolean(decoded_values.blend_surface_c()) + + " mrt3 = " + print_boolean(decoded_values.blend_surface_d()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return std::make_tuple( - to_user_clip_plane_op(value & 0xf), - to_user_clip_plane_op((value >> 4) & 0xf), - to_user_clip_plane_op((value >> 8) & 0xf), - to_user_clip_plane_op((value >> 12) & 0xf), - to_user_clip_plane_op((value >> 16) & 0xf), - to_user_clip_plane_op((value >> 20) & 0xf) - ); - } - static void commit_rsx_state(rsx_state &state, - std::tuple &&decoded_values) + struct decoded_type { - state.m_clip_plane_0_enabled = std::get<0>(decoded_values); - state.m_clip_plane_1_enabled = std::get<1>(decoded_values); - state.m_clip_plane_2_enabled = std::get<2>(decoded_values); - state.m_clip_plane_3_enabled = std::get<3>(decoded_values); - state.m_clip_plane_4_enabled = std::get<4>(decoded_values); - state.m_clip_plane_5_enabled = std::get<5>(decoded_values); - } + private: + union + { + u32 raw_data; + bitfield_decoder_t<0, 4> clip_plane0; + bitfield_decoder_t<4, 4> clip_plane1; + bitfield_decoder_t<8, 4> clip_plane2; + bitfield_decoder_t<12, 4> clip_plane3; + bitfield_decoder_t<16, 4> clip_plane4; + bitfield_decoder_t<20, 4> clip_plane5; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_data = raw_value; } - static std::string dump(std::tuple &&decoded_values) + user_clip_plane_op clip_plane0() const + { + return to_user_clip_plane_op(m_data.clip_plane0); + } + + user_clip_plane_op clip_plane1() const + { + return to_user_clip_plane_op(m_data.clip_plane1); + } + + user_clip_plane_op clip_plane2() const + { + return to_user_clip_plane_op(m_data.clip_plane2); + } + + user_clip_plane_op clip_plane3() const + { + return to_user_clip_plane_op(m_data.clip_plane3); + } + + user_clip_plane_op clip_plane4() const + { + return to_user_clip_plane_op(m_data.clip_plane4); + } + + user_clip_plane_op clip_plane5() const + { + return to_user_clip_plane_op(m_data.clip_plane5); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "User clip: UC0 = " + print_user_clip_plane_op(std::get<0>(decoded_values)) + - " UC1 = " + print_user_clip_plane_op(std::get<1>(decoded_values)) + - " UC2 = " + print_user_clip_plane_op(std::get<2>(decoded_values)) + - " UC2 = " + print_user_clip_plane_op(std::get<2>(decoded_values)) + - " UC2 = " + print_user_clip_plane_op(std::get<2>(decoded_values)) + - " UC2 = " + print_user_clip_plane_op(std::get<2>(decoded_values)); + return "User clip: UC0 = " + to_string(decoded_values.clip_plane0()) + + " UC1 = " + to_string(decoded_values.clip_plane1()) + + " UC2 = " + to_string(decoded_values.clip_plane2()) + + " UC2 = " + to_string(decoded_values.clip_plane3()) + + " UC2 = " + to_string(decoded_values.clip_plane4()) + + " UC2 = " + to_string(decoded_values.clip_plane5()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return (value >> 3) + (value & 7) / 8.f; - } - - static void commit_rsx_state(rsx_state &state, f32 &&decoded_values) + struct decoded_type { - state.m_line_width = decoded_values; - } + private: + union + { + u32 raw_data; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_data = raw_value; } - static std::string dump(f32 &&decoded_values) + f32 line_width() const + { + return (m_data.raw_data >> 3) + (m_data.raw_data & 7) / 8.f; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Line width: " + std::to_string(decoded_values); + return "Line width: " + std::to_string(decoded_values.line_width()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return std::make_tuple( - to_surface_color_format(value & 0x1f), - to_surface_depth_format((value >> 5) & 0x7), - to_surface_antialiasing((value >> 12) & 0xf), - static_cast((value >> 16) & 0xff), - static_cast((value >> 24) & 0xff) - ); - } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_surface_color = std::get<0>(decoded_values); - state.m_surface_depth_format = std::get<1>(decoded_values); - state.m_surface_antialias = std::get<2>(decoded_values); - state.m_surface_log2_width = std::get<3>(decoded_values); - state.m_surface_log2_height = std::get<4>(decoded_values); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 5> color_fmt; + bitfield_decoder_t<5, 3> depth_fmt; + bitfield_decoder_t<12, 4> antialias; + bitfield_decoder_t<16, 8> log2width; + bitfield_decoder_t<24, 8> log2height; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(std::tuple &&decoded_values) + surface_color_format color_fmt() const + { + return to_surface_color_format(m_data.color_fmt); + } + + surface_depth_format depth_fmt() const + { + return to_surface_depth_format(m_data.depth_fmt); + } + + surface_antialiasing antialias() const + { + return to_surface_antialiasing(m_data.antialias); + } + + u8 log2width() const + { + return bitfield_decoder_t<16, 8>(m_data.log2width); + } + + u8 log2height() const + { + return bitfield_decoder_t<24, 8>(m_data.log2height); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Surface: Color format = " + print_surface_color_format(std::get<0>(decoded_values)) + - " DepthStencil format = " + print_depth_stencil_surface_format(std::get<1>(decoded_values)) + - " Anti aliasing =" + print_surface_antialiasing(std::get<2>(decoded_values)) + - " w = " + std::to_string(std::get<3>(decoded_values)) + - " h = " + std::to_string(std::get<4>(decoded_values)); + return "Surface: Color format = " + to_string(decoded_values.color_fmt()) + + " DepthStencil format = " + to_string(decoded_values.depth_fmt()) + + " Anti aliasing =" + to_string(decoded_values.antialias()) + + " w = " + std::to_string(decoded_values.log2width()) + + " h = " + std::to_string(decoded_values.log2height()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return std::make_tuple(value >> 8, static_cast(value & 0xff)); - } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_z_clear_value = std::get<0>(decoded_values); - state.m_stencil_clear_value = std::get<1>(decoded_values); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<8, 24> clear_z; + bitfield_decoder_t<0, 8> clear_stencil; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(std::tuple &&decoded_values) + u8 clear_stencil() const + { + return m_data.clear_stencil; + } + + u32 clear_z() const + { + return m_data.clear_z; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Clear: Z = " + std::to_string(std::get<0>(decoded_values)) + - " Stencil = " + std::to_string(std::get<1>(decoded_values)); + return "Clear: Z = " + std::to_string(decoded_values.clear_z()) + + " Stencil = " + std::to_string(decoded_values.clear_stencil()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return std::make_tuple(index_array_type(value >> 4), value & 0xf); - } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_index_type = std::get<0>(decoded_values); - state.m_index_array_location = std::get<1>(decoded_values); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 4> index_dma; + bitfield_decoder_t<4, 28> type; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(std::tuple &&decoded_values) + u8 index_dma() const + { + return m_data.index_dma; + } + + index_array_type type() const + { + return to_index_array_type(m_data.type); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Index: type = " + print_index_type(std::get<0>(decoded_values)) + - " dma = " + std::to_string(std::get<1>(decoded_values)); + return "Index: type = " + to_string(decoded_values.type()) + + " dma = " + std::to_string(decoded_values.index_dma()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return value; - } - - static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + struct decoded_type { - state.m_surface_a_dma = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> dma_surface_a; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(u32 &&decoded_values) + u32 dma_surface_a() const + { + return m_data.dma_surface_a; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Surface: A DMA = " + std::to_string(decoded_values); + return "Surface: A DMA = " + std::to_string(decoded_values.dma_surface_a()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return value; - } - - static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + struct decoded_type { - state.m_surface_b_dma = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> dma_surface_b; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(u32 &&decoded_values) + u32 dma_surface_b() const + { + return m_data.dma_surface_b; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Surface: B DMA = " + std::to_string(decoded_values); + return "Surface: B DMA = " + std::to_string(decoded_values.dma_surface_b()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return value; - } - - static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + struct decoded_type { - state.m_surface_c_dma = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> dma_surface_c; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(u32 &&decoded_values) + u32 dma_surface_c() const + { + return m_data.dma_surface_c; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Surface: C DMA = " + std::to_string(decoded_values); + return "Surface: C DMA = " + std::to_string(decoded_values.dma_surface_c()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return value; - } - - static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + struct decoded_type { - state.m_surface_d_dma = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> dma_surface_d; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(u32 &&decoded_values) + u32 dma_surface_d() const + { + return m_data.dma_surface_d; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Surface: D DMA = " + std::to_string(decoded_values); + return "Surface: D DMA = " + std::to_string(decoded_values.dma_surface_d()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return value; - } - - static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + struct decoded_type { - state.m_surface_z_dma = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> dma_surface_z; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(u32 &&decoded_values) + u32 dma_surface_z() const + { + return m_data.dma_surface_z; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Surface: Z DMA = " + std::to_string(decoded_values); + return "Surface: Z DMA = " + std::to_string(decoded_values.dma_surface_z()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return value; - } - - static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + struct decoded_type { - state.m_blit_engine_input_location = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> context_dma; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(u32 &&decoded_values) + u32 context_dma() const + { + return m_data.context_dma; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "NV3089: input DMA = " + std::to_string(decoded_values); + return "NV3089: input DMA = " + std::to_string(decoded_values.context_dma()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_blit_engine_output_location_nv3062> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "NV3062: output DMA = " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> output_dma; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 output_dma() const + { + return m_data.output_dma; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "NV3062: output DMA = " + std::to_string(decoded_values.output_dma()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return value; - } - - static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + struct decoded_type { - state.m_blit_engine_nv309E_location = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> context_dma; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(u32 &&decoded_values) + u32 context_dma() const + { + return m_data.context_dma; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "NV309E: output DMA = " + std::to_string(decoded_values); + return "NV309E: output DMA = " + std::to_string(decoded_values.context_dma()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return value; - } - - static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + struct decoded_type { - state.m_nv0039_output_location = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> output_dma; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(u32 &&decoded_values) + u32 output_dma() const + { + return m_data.output_dma; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "NV0039: output DMA = " + std::to_string(decoded_values); + return "NV0039: output DMA = " + std::to_string(decoded_values.output_dma()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return value; - } - - static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + struct decoded_type { - state.m_nv0039_input_location = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> input_dma; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(u32 &&decoded_values) + u32 input_dma() const + { + return m_data.input_dma; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "NV0039: input DMA = " + std::to_string(decoded_values); + return "NV0039: input DMA = " + std::to_string(decoded_values.input_dma()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return blit_engine::to_context_dma(value); - } - - static void commit_rsx_state(rsx_state &state, blit_engine::context_dma &&decoded_values) + struct decoded_type { - state.m_context_dma_report = decoded_values; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> context_dma_report; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(blit_engine::context_dma &&decoded_values) + blit_engine::context_dma context_dma_report() const + { + return blit_engine::to_context_dma(m_data.context_dma_report); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Report: context DMA = " + print_context_dma(decoded_values); + return "Report: context DMA = " + to_string(decoded_values.context_dma_report()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return std::make_tuple(static_cast(value), - blit_engine::to_transfer_origin(value >> 16), - blit_engine::to_transfer_interpolator(value >> 24)); - } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_blit_engine_input_pitch = std::get<0>(decoded_values); - state.m_blit_engine_input_origin = std::get<1>(decoded_values); - state.m_blit_engine_input_inter = std::get<2>(decoded_values); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> format; + bitfield_decoder_t<16, 8> transfer_origin; + bitfield_decoder_t<24, 8> transfer_interpolator; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(std::tuple &&decoded_values) + u16 format() const + { + return m_data.format; + } + + blit_engine::transfer_origin transfer_origin() const + { + return blit_engine::to_transfer_origin(m_data.transfer_origin); + } + + blit_engine::transfer_interpolator transfer_interpolator() const + { + return blit_engine::to_transfer_interpolator(m_data.transfer_interpolator); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "NV3089: input fmt " + std::to_string(std::get<0>(decoded_values)) + - " origin = " + print_transfer_origin(std::get<1>(decoded_values)) + - " interp = " + print_transfer_interpolator(std::get<2>(decoded_values)); + return "NV3089: input fmt " + std::to_string(decoded_values.format()) + + " origin = " + to_string(decoded_values.transfer_origin()) + + " interp = " + to_string(decoded_values.transfer_interpolator()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return std::make_tuple(blit_engine::to_transfer_destination_format(value), static_cast(value >> 16), static_cast(value >> 24)); - } - - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + struct decoded_type { - state.m_blit_engine_output_format_nv309E = std::get<0>(decoded_values); - state.m_nv309e_sw_height_log2 = std::get<1>(decoded_values); - state.m_nv309e_sw_width_log2 = std::get<2>(decoded_values); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> transfer_destination_fmt; + bitfield_decoder_t<16, 8> sw_height_log2; + bitfield_decoder_t<24, 8> sw_width_log2; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(std::tuple &&decoded_values) + blit_engine::transfer_destination_format format() const + { + return blit_engine::to_transfer_destination_format(m_data.transfer_destination_fmt); + } + + u8 sw_height_log2() const + { + return m_data.sw_height_log2; + } + + u8 sw_width_log2() const + { + return m_data.sw_width_log2; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "NV309E: output fmt = " + print_transfer_destination_format(std::get<0>(decoded_values)) + - " log2-width = " + std::to_string(std::get<1>(decoded_values)) + - " log2-height = " + std::to_string(std::get<2>(decoded_values)); + return "NV309E: output fmt = " + to_string(decoded_values.format()) + + " log2-width = " + std::to_string(decoded_values.sw_width_log2()) + + " log2-height = " + std::to_string(decoded_values.sw_height_log2()); } }; template<> struct registers_decoder { + struct decoded_type + { + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 8> input_fmt; + bitfield_decoder_t<8, 8> output_fmt; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u8 input_format() const + { + return m_data.input_fmt; + } + + u8 output_format() const + { + return m_data.output_fmt; + } + }; + static auto decode(u32 value) { return std::make_tuple(static_cast(value & 0xff), static_cast(value >> 8)); } - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + static std::string dump(decoded_type &&decoded_values) { - state.m_nv0039_input_format = std::get<0>(decoded_values); - state.m_nv0039_output_format = std::get<1>(decoded_values); - } - - static std::string dump(std::tuple &&decoded_values) - { - return "NV0039: input format = " + std::to_string(std::get<0>(decoded_values)) + - " output format = " + std::to_string(std::get<1>(decoded_values)); + return "NV0039: input format = " + std::to_string(decoded_values.input_format()) + + " output format = " + std::to_string(decoded_values.output_format()); } }; template<> struct registers_decoder - : public as_u16x2<&rsx_state::m_blend_color_16b_b, &rsx_state::m_blend_color_16b_a> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "Blend color: 16b BA = " + std::to_string(std::get<0>(decoded_values)) + - ", " + std::to_string(std::get<1>(decoded_values)); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> blue; + bitfield_decoder_t<16, 16> alpha; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u8 blue() const + { + return m_data.blue; + } + + u8 alpha() const + { + return m_data.alpha; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Blend color: 16b BA = " + std::to_string(decoded_values.blue()) + + ", " + std::to_string(decoded_values.alpha()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_blend_color> { - static std::string dump(u32 &&decoded_values) + struct decoded_type + { + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> red16; + bitfield_decoder_t<16, 16> green16; + bitfield_decoder_t<0, 8> red8; + bitfield_decoder_t<8, 8> green8; + bitfield_decoder_t<16, 8> blue8; + bitfield_decoder_t<24, 8> alpha8; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u8 red16() const + { + return m_data.red16; + } + + u8 green16() const + { + return m_data.green16; + } + + u8 red8() const + { + return m_data.red8; + } + + u8 green8() const + { + return m_data.green8; + } + + u8 blue8() const + { + return m_data.blue8; + } + + u8 alpha8() const + { + return m_data.alpha8; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - auto rgba8 = split_reg_quad_uchar(decoded_values); - auto rg16 = split_reg_half_uint_decode::decode(decoded_values); return "Blend color: 8b RGBA = " + - std::to_string(std::get<0>(rgba8)) + ", " + std::to_string(std::get<1>(rgba8)) + ", " + std::to_string(std::get<2>(rgba8)) + ", " + std::to_string(std::get<3>(rgba8)) + - " 16b RG = " + std::to_string(std::get<0>(rg16)) + ", " + std::to_string(std::get<1>(rg16)); + std::to_string(decoded_values.red8()) + ", " + std::to_string(decoded_values.green8()) + ", " + std::to_string(decoded_values.blue8()) + ", " + std::to_string(decoded_values.alpha8()) + + " 16b RG = " + std::to_string(decoded_values.red16()) + ", " + std::to_string(decoded_values.green16()); } }; template<> struct registers_decoder - : public as_u16x2<&rsx_state::m_blit_engine_in_x, &rsx_state::m_blit_engine_in_y> { - static std::string dump(std::tuple &&decoded_values) + struct decoded_type { - return "NV3089: in x = " + std::to_string(std::get<0>(decoded_values) / 16.f) + - " y = " + std::to_string(std::get<1>(decoded_values) / 16.f); + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 16> x; + bitfield_decoder_t<16, 16> y; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u16 x() const + { + return m_data.x; + } + + u16 y() const + { + return m_data.y; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "NV3089: in x = " + std::to_string(decoded_values.x() / 16.f) + + " y = " + std::to_string(decoded_values.y() / 16.f); } }; template<> -struct registers_decoder : public as_unused +struct registers_decoder { + struct decoded_type + { + decoded_type(u32) {}; + }; + static std::string dump(u32 &&decoded_values) { return "(nop)"; @@ -2112,8 +4009,13 @@ struct registers_decoder : public as_unused }; template<> -struct registers_decoder : public as_unused +struct registers_decoder { + struct decoded_type + { + decoded_type(u32) {}; + }; + static std::string dump(u32 &&decoded_values) { return "(invalidate vertex cache file)"; @@ -2121,8 +4023,13 @@ struct registers_decoder : public as_unused }; template<> -struct registers_decoder : public as_unused +struct registers_decoder { + struct decoded_type + { + decoded_type(u32) {}; + }; + static std::string dump(u32 &&decoded_values) { return "(invalidate vertex file)"; @@ -2132,97 +4039,150 @@ struct registers_decoder : public as_unused template<> struct registers_decoder { - static auto decode(u32 value) + struct decoded_type { - return std::make_tuple( - !!(value & 0x1), - !!((value >> 4) & 0x1), - !!((value >> 8) & 0x1), - static_cast(value >> 16) - ); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 1> msaa_enabled; + bitfield_decoder_t<4, 1> msaa_alpha_to_coverage; + bitfield_decoder_t<8, 1> msaa_alpha_to_one; + bitfield_decoder_t<16, 16> msaa_sample_mask; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) - { - state.m_msaa_enabled = std::get<0>(decoded_values); - state.m_msaa_alpha_to_coverage = std::get<1>(decoded_values); - state.m_msaa_alpha_to_one = std::get<2>(decoded_values); - state.m_msaa_sample_mask = std::get<3>(decoded_values); - } + bool msaa_enabled() const + { + return bool(m_data.msaa_enabled); + } - static std::string dump(std::tuple &&decoded_values) + bool msaa_alpha_to_coverage() const + { + return bool(m_data.msaa_alpha_to_coverage); + } + + bool msaa_alpha_to_one() const + { + return bool(m_data.msaa_alpha_to_one); + } + + u16 msaa_sample_mask() const + { + return m_data.msaa_sample_mask; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Anti_aliasing: " + print_boolean(std::get<0>(decoded_values)) + - " alpha_to_coverage = " + print_boolean(std::get<1>(decoded_values)) + - " alpha_to_one = " + print_boolean(std::get<2>(decoded_values)) + - " sample_mask = " + std::to_string(std::get<3>(decoded_values)); + return "Anti_aliasing: " + print_boolean(decoded_values.msaa_enabled()) + + " alpha_to_coverage = " + print_boolean(decoded_values.msaa_alpha_to_coverage()) + + " alpha_to_one = " + print_boolean(decoded_values.msaa_alpha_to_one()) + + " sample_mask = " + std::to_string(decoded_values.msaa_sample_mask()); } }; template<> struct registers_decoder { - static auto decode(u32 value) + struct decoded_type { - return to_shading_mode(value); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> shading; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static void commit_rsx_state(rsx_state &state, rsx::shading_mode &&decoded_values) - { - state.m_shading_mode = decoded_values; - } + shading_mode shading() const + { + return to_shading_mode(m_data.shading); + } + }; - static std::string dump(rsx::shading_mode &&decoded_values) + static std::string dump(decoded_type &&decoded_values) { - return "Shading mode: " + print_shading_mode(decoded_values); + return "Shading mode: " + to_string(decoded_values.shading()); } }; template<> struct registers_decoder { - static auto decode(u32 value) + struct decoded_type { - return to_polygon_mode(value); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> front_polygon_mode; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static void commit_rsx_state(rsx_state &state, rsx::polygon_mode &&decoded_values) - { - state.m_front_polygon_mode = decoded_values; - } + polygon_mode front_polygon_mode() const + { + return to_polygon_mode(m_data.front_polygon_mode); + } + }; - static std::string dump(rsx::polygon_mode &&decoded_values) + static std::string dump(decoded_type &&decoded_values) { - return "Front polygon mode: " + print_polygon_mode(decoded_values); + return "Front polygon mode: " + to_string(decoded_values.front_polygon_mode()); } }; template<> struct registers_decoder { - static auto decode(u32 value) + struct decoded_type { - return to_polygon_mode(value); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> back_polygon_mode; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static void commit_rsx_state(rsx_state &state, rsx::polygon_mode &&decoded_values) - { - state.m_back_polygon_mode = decoded_values; - } + polygon_mode back_polygon_mode() const + { + return to_polygon_mode(m_data.back_polygon_mode); + } + }; - static std::string dump(rsx::polygon_mode &&decoded_values) + static std::string dump(decoded_type &&decoded_values) { - return "back polygon mode: " + print_polygon_mode(decoded_values); + return "back polygon mode: " + to_string(decoded_values.back_polygon_mode()); } }; template<> struct registers_decoder - : as_u32<&rsx_state::m_transform_constant_file_pointer> { - static std::string dump(u32 &&decoded_values) + struct decoded_type { - return "Set transform constant pointer at " + std::to_string(decoded_values); + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + u32 transform_constant_load() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) + { + return "Set transform constant pointer at " + std::to_string(decoded_values.transform_constant_load()); } }; @@ -2268,22 +4228,28 @@ struct registers_decoder template struct transform_constant_helper { - static auto decode(u32 value) { - return value; - } + struct decoded_type + { + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } + + f32 constant_value() const + { + return reinterpret_cast(m_data.raw_value); + } + }; static constexpr u32 reg = index / 4; static constexpr u8 subreg = index % 4; - static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + static std::string dump(decoded_type &&decoded_values) { - u32 load = state.m_transform_constant_file_pointer; - state.transform_constants[load + reg].rgba[subreg] = (f32&)decoded_values; - } - - static std::string dump(u32 &&decoded_values) - { - return "TransformConstant[base + " + std::to_string(reg) + "]." + get_subreg_name(subreg) + " = " + std::to_string((f32&)decoded_values); + return "TransformConstant[base + " + std::to_string(reg) + "]." + get_subreg_name(subreg) + " = " + std::to_string(decoded_values.constant_value()); } }; @@ -2295,37 +4261,51 @@ EXPAND_RANGE_32(0, TRANSFORM_CONSTANT) template struct transform_program_helper { - static auto decode(u32 value) { - return value; - } - - static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + struct decoded_type { - u32 &load = state.m_transform_program_pointer; - state.transform_program[load++] = decoded_values; - } + private: + union + { + u32 raw_value; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(u32 &&decoded_values) + u32 value() const + { + return m_data.raw_value; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Transform Program (" + std::to_string(index) + "):"+ std::to_string(decoded_values); + return "Transform Program (" + std::to_string(index) + "):"+ std::to_string(decoded_values.value()); } }; template<> struct registers_decoder { - static auto decode(u32 value) { - return value; - } - - static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + struct decoded_type { - state.m_transform_program_pointer = decoded_values << 2; - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 32> transform_program_load; + } m_data; + public: + decoded_type(u32 raw_value) { m_data.raw_value = raw_value; } - static std::string dump(u32 &&decoded_values) + u32 transform_program_load() const + { + return m_data.transform_program_load; + } + }; + + static std::string dump(decoded_type &&decoded_values) { - return "Transform Program pointer :" + std::to_string(decoded_values); + return "Transform Program pointer :" + std::to_string(decoded_values.transform_program_load()); } }; @@ -2336,32 +4316,50 @@ EXPAND_RANGE_512(0, TRANSFORM_PROGRAM) template struct vertex_array_helper { - static auto decode(u32 value) + struct decoded_type { - u16 frequency = value >> 16; - u8 stride = (value >> 8) & 0xff; - u8 size = (value >> 4) & 0xf; - rsx::vertex_base_type type = rsx::to_vertex_base_type(value & 0xf); - return std::make_tuple(frequency, stride, size, type); - } + private: + union + { + u32 raw_value; + bitfield_decoder_t<0, 4> type; + bitfield_decoder_t<4, 4> size; + bitfield_decoder_t<8, 8> stride; + bitfield_decoder_t<16, 16> frequency; + } m_data; + public: + decoded_type(u32 v) { m_data.raw_value = v; } - static void commit_rsx_state(rsx::rsx_state &state, std::tuple &&decoded_values) - { - state.vertex_arrays_info[index].frequency = std::get<0>(decoded_values); - state.vertex_arrays_info[index].stride = std::get<1>(decoded_values); - state.vertex_arrays_info[index].size = std::get<2>(decoded_values); - state.vertex_arrays_info[index].type = std::get<3>(decoded_values); - } + u16 frequency() const + { + return m_data.frequency; + } - static std::string dump(std::tuple &&decoded_values) + u8 stride() const + { + return m_data.stride; + } + + u8 size() const + { + return m_data.size; + } + + rsx::vertex_base_type type() const + { + return rsx::to_vertex_base_type(m_data.type); + } + }; + + static std::string dump(decoded_type &&decoded_values) { - if (std::get<2>(decoded_values) == 0) + if (decoded_values.size() == 0) return "(disabled)"; - return "Vertex array " + std::to_string(index) + ": Type = " + print_vertex_attribute_format(std::get<3>(decoded_values)) + - " size = " + std::to_string(std::get<2>(decoded_values)) + - " stride = " + std::to_string(std::get<1>(decoded_values)) + - " frequency = " + std::to_string(std::get<0>(decoded_values)); + return "Vertex array " + std::to_string(index) + ": Type = " + print_vertex_attribute_format(decoded_values.type()) + + " size = " + std::to_string(decoded_values.size()) + + " stride = " + std::to_string(decoded_values.stride()) + + " frequency = " + std::to_string(decoded_values.frequency()); } }; @@ -2373,19 +4371,22 @@ EXPAND_RANGE_16(0, VERTEX_DATA_ARRAY_FORMAT) template struct vertex_array_offset_helper { - static auto decode(u32 value) + struct decoded_type { - return value; - } + private: + u32 raw_value; + public: + decoded_type(u32 v) : raw_value(v) {} - static void commit_rsx_state(rsx::rsx_state &state, u32 &&decoded_values) - { - state.vertex_arrays_info[index].m_offset = decoded_values; - } + u32 offset() const + { + return raw_value; + } + }; - static std::string dump(u32 &&decoded_values) + static std::string dump(decoded_type &&decoded_values) { - return "Vertex array " + std::to_string(index) + ": Offset = " + std::to_string(decoded_values); + return "Vertex array " + std::to_string(index) + ": Offset = " + std::to_string(decoded_values.offset()); } }; @@ -2394,70 +4395,74 @@ struct vertex_array_offset_helper EXPAND_RANGE_16(0, VERTEX_DATA_ARRAY_OFFSET) -template struct vertex_data_type_from_element_type; -template<> struct vertex_data_type_from_element_type { static constexpr rsx::vertex_base_type type = rsx::vertex_base_type::f; }; -template<> struct vertex_data_type_from_element_type { static constexpr rsx::vertex_base_type type = rsx::vertex_base_type::sf; }; -template<> struct vertex_data_type_from_element_type { static constexpr rsx::vertex_base_type type = rsx::vertex_base_type::ub; }; -template<> struct vertex_data_type_from_element_type { static constexpr rsx::vertex_base_type type = rsx::vertex_base_type::s1; }; - template -struct vertex_type_namer; +struct register_vertex_printer; template -struct vertex_type_namer +struct register_vertex_printer { - static std::string get() + static std::string type() { return "float" + std::to_string(count); } + + static std::string value(u32 v) + { + return std::to_string(reinterpret_cast(v)); + } }; template -struct vertex_type_namer +struct register_vertex_printer { - static std::string get() + static std::string type() { return "short" + std::to_string(count); } + + static std::string value(u32 v) + { + return std::to_string(v & 0xffff) + std::to_string(v >> 16); + } }; template<> -struct vertex_type_namer +struct register_vertex_printer { - static std::string get() + static std::string type() { return "uchar4"; } + + static std::string value(u32 v) + { + return std::to_string(v & 0xff) + std::to_string((v >> 8) & 0xff) + std::to_string((v >> 16) & 0xff) + std::to_string((v >> 24) & 0xff); + } }; template struct register_vertex_helper { - static auto decode(u32 value) + struct decoded_type { - return value; - } + private: + u32 m_raw_value; + public: + decoded_type(u32 v) : m_raw_value(v) {} + u32 value() const + { + return m_raw_value; + } + }; static const size_t increment_per_array_index = (count * sizeof(type)) / sizeof(u32); - static const size_t attribute_index = index / increment_per_array_index; static const size_t vertex_subreg = index % increment_per_array_index; - static void commit_rsx_state(rsx::rsx_state &state, u32 &&decoded_values) + static std::string dump(decoded_type&& decoded_values) { - auto& info = state.register_vertex_info[attribute_index]; - - info.type = vertex_data_type_from_element_type::type; - info.size = count; - info.frequency = 0; - info.stride = 0; - state.register_vertex_info[attribute_index].data[vertex_subreg] = decoded_values; - } - - static std::string dump(u32&& decoded_values) - { - return "register vertex " + std::to_string(attribute_index) + " as " + vertex_type_namer::get() + ": " + - std::to_string(decoded_values); + return "register vertex " + std::to_string(attribute_index) + " as " + register_vertex_printer::type() + ": " + + register_vertex_printer::value(decoded_values.value()); } }; @@ -2646,13 +4651,6 @@ constexpr std::integer_sequence #include +#include cfg::map_entry g_cfg_rsx_frame_limit(cfg::root.video, "Frame limit", { @@ -24,7 +25,14 @@ cfg::map_entry g_cfg_rsx_frame_limit(cfg::root.video, "Frame limit", namespace rsx { rsx_state method_registers; - rsx_method_t methods[0x10000 >> 2]{}; + using rsx_method_t = void(*)(class thread*, u32); + std::unordered_map methods{}; + + template struct vertex_data_type_from_element_type; + template<> struct vertex_data_type_from_element_type { static const vertex_base_type type = vertex_base_type::f; }; + template<> struct vertex_data_type_from_element_type { static const vertex_base_type type = vertex_base_type::sf; }; + template<> struct vertex_data_type_from_element_type { static const vertex_base_type type = vertex_base_type::ub; }; + template<> struct vertex_data_type_from_element_type { static const vertex_base_type type = vertex_base_type::s1; }; namespace nv406e { @@ -67,6 +75,99 @@ namespace rsx (arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff)); } + template + force_inline void set_vertex_data_impl(thread* rsx, u32 arg) + { + static const size_t increment_per_array_index = (count * sizeof(type)) / sizeof(u32); + + static const size_t attribute_index = index / increment_per_array_index; + static const size_t vertex_subreg = index % increment_per_array_index; + + auto& info = rsx::method_registers.register_vertex_info[attribute_index]; + + info.type = vertex_data_type_from_element_type::type; + info.size = count; + info.frequency = 0; + info.stride = 0; + rsx::method_registers.register_vertex_info[attribute_index].data[vertex_subreg] = arg; + } + + template + struct set_vertex_data4ub_m + { + force_inline static void impl(thread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + }; + + template + struct set_vertex_data1f_m + { + force_inline static void impl(thread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + }; + + template + struct set_vertex_data2f_m + { + force_inline static void impl(thread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + }; + + template + struct set_vertex_data3f_m + { + force_inline static void impl(thread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + }; + + template + struct set_vertex_data4f_m + { + force_inline static void impl(thread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + }; + + template + struct set_vertex_data2s_m + { + force_inline static void impl(thread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + }; + + template + struct set_vertex_data4s_m + { + force_inline static void impl(thread* rsx, u32 arg) + { + set_vertex_data_impl(rsx, arg); + } + }; + + template + struct set_vertex_data_array_format + { + force_inline static void impl(thread* rsx, u32 arg) + { + const typename rsx::registers_decoder::decoded_type decoded_value(arg); + rsx::method_registers.vertex_arrays_info[index].frequency = decoded_value.frequency(); + rsx::method_registers.vertex_arrays_info[index].stride = decoded_value.stride(); + rsx::method_registers.vertex_arrays_info[index].size = decoded_value.size(); + rsx::method_registers.vertex_arrays_info[index].type = decoded_value.type(); + } + }; + force_inline void draw_arrays(thread* rsx, u32 arg) { rsx->draw_command = rsx::draw_command::array; @@ -97,10 +198,24 @@ namespace rsx { force_inline static void impl(thread* rsxthr, u32 arg) { + static constexpr u32 reg = index / 4; + static constexpr u8 subreg = index % 4; + + u32 load = rsx::method_registers.transform_constant_load(); + rsx::method_registers.transform_constants[load + reg].rgba[subreg] = (f32&)arg; rsxthr->m_transform_constants_dirty = true; } }; + template + struct set_transform_program + { + force_inline static void impl(thread* rsx, u32 arg) + { + method_registers.commit_4_transform_program_instructions(index); + } + }; + force_inline void set_begin_end(thread* rsxthr, u32 arg) { if (arg) @@ -657,7 +772,8 @@ namespace rsx rsx_state::rsx_state() : fragment_textures(fill_array(registers, std::make_index_sequence<16>())), - vertex_textures(fill_array(registers, std::make_index_sequence<4>())) + vertex_textures(fill_array(registers, std::make_index_sequence<4>())), + vertex_arrays_info(fill_array(registers, std::make_index_sequence<16>())) { } @@ -672,140 +788,77 @@ namespace rsx //setup method registers std::memset(registers.data(), 0, registers.size() * sizeof(u32)); - m_primitive_type = primitive_type::triangles; - m_transform_program_pointer = 0; + registers[NV4097_SET_COLOR_MASK] = CELL_GCM_COLOR_MASK_R | CELL_GCM_COLOR_MASK_G | CELL_GCM_COLOR_MASK_B | CELL_GCM_COLOR_MASK_A; + registers[NV4097_SET_SCISSOR_HORIZONTAL] = (4096 << 16) | 0; + registers[NV4097_SET_SCISSOR_VERTICAL] = (4096 << 16) | 0; - m_color_mask_r = true; - m_color_mask_g = true; - m_color_mask_b = true; - m_color_mask_a = true; + registers[NV4097_SET_ALPHA_FUNC] = CELL_GCM_ALWAYS; + registers[NV4097_SET_ALPHA_REF] = 0; - m_scissor_width = 4096; - m_scissor_height = 4096; - m_scissor_origin_x = 0; - m_scissor_origin_y = 0; + registers[NV4097_SET_BLEND_FUNC_SFACTOR] = (CELL_GCM_ONE << 16) | CELL_GCM_ONE; + registers[NV4097_SET_BLEND_FUNC_DFACTOR] = (CELL_GCM_ZERO << 16) | CELL_GCM_ZERO; + registers[NV4097_SET_BLEND_COLOR] = 0; + registers[NV4097_SET_BLEND_COLOR2] = 0; + registers[NV4097_SET_BLEND_EQUATION] = (0x8006 << 16) | 0x8006; // (add) - m_alpha_test_enabled = false; - m_alpha_func = rsx::comparison_function::always; - m_alpha_ref = 0; + registers[NV4097_SET_STENCIL_MASK] = 0xff; + registers[NV4097_SET_STENCIL_FUNC] = CELL_GCM_ALWAYS; + registers[NV4097_SET_STENCIL_FUNC_REF] = 0x00; + registers[NV4097_SET_STENCIL_FUNC_MASK] = 0xff; +/* registers[NV4097_SET_STENCIL_OP_FAIL] = CELL_GCM_KEEP; + registers[NV4097_SET_STENCIL_OP_ZFAIL] = CELL_GCM_KEEP; + registers[NV4097_SET_STENCIL_OP_ZPASS] = CELL_GCM_KEEP;*/ - m_blend_enabled = false; - m_blend_enabled_surface_1 = false; - m_blend_enabled_surface_2 = false; - m_blend_enabled_surface_3 = false; - m_blend_func_sfactor_rgb = rsx::blend_factor::one; - m_blend_func_sfactor_a = rsx::blend_factor::one; - m_blend_func_dfactor_rgb = rsx::blend_factor::one; - m_blend_func_dfactor_a = rsx::blend_factor::one; + registers[NV4097_SET_BACK_STENCIL_MASK] = 0xff; + registers[NV4097_SET_BACK_STENCIL_FUNC] = CELL_GCM_ALWAYS; + registers[NV4097_SET_BACK_STENCIL_FUNC_REF] = 0x00; + registers[NV4097_SET_BACK_STENCIL_FUNC_MASK] = 0xff; +/* registers[NV4097_SET_BACK_STENCIL_OP_FAIL] = CELL_GCM_KEEP; + registers[NV4097_SET_BACK_STENCIL_OP_ZFAIL] = CELL_GCM_KEEP; + registers[NV4097_SET_BACK_STENCIL_OP_ZPASS] = CELL_GCM_KEEP;*/ - m_blend_color_16b_a = 0; - m_blend_color_16b_b = 0; - m_blend_color = 0; +// registers[NV4097_SET_SHADE_MODE] = CELL_GCM_SMOOTH; - m_blend_equation_rgb = rsx::blend_equation::add; - m_blend_equation_a = rsx::blend_equation::add; +// registers[NV4097_SET_LOGIC_OP] = CELL_GCM_COPY; - m_stencil_test_enabled = false; - m_two_sided_stencil_test_enabled = false; - m_stencil_mask = 0xff; - m_stencil_func = rsx::comparison_function::always; - m_stencil_func_ref = 0; - m_stencil_func_mask = 0xff; - m_stencil_op_fail = rsx::stencil_op::keep; - m_stencil_op_zfail = rsx::stencil_op::keep; - m_stencil_op_zpass = rsx::stencil_op::keep; + (f32&)registers[NV4097_SET_DEPTH_BOUNDS_MIN] = 0.f; + (f32&)registers[NV4097_SET_DEPTH_BOUNDS_MAX] = 1.f; - m_back_stencil_mask = 0xff; - m_back_stencil_func = rsx::comparison_function::always; - m_back_stencil_func_ref = 0; - m_back_stencil_func_mask = 0xff; - m_back_stencil_op_fail = rsx::stencil_op::keep; - m_back_stencil_op_zfail = rsx::stencil_op::keep; - m_back_stencil_op_zpass = rsx::stencil_op::keep; + (f32&)registers[NV4097_SET_CLIP_MIN] = 0.f; + (f32&)registers[NV4097_SET_CLIP_MAX] = 1.f; - m_shading_mode = rsx::shading_mode::smooth; - - m_logic_op_enabled = false; - m_logic_operation = rsx::logic_op::logic_copy; - - m_depth_bounds_test_enabled = false; - m_depth_bounds_min = 0.f; - m_depth_bounds_max = 1.f; - - m_clip_min = 0.f; - m_clip_max = 1.f; - - m_line_width = 1.f; + registers[NV4097_SET_LINE_WIDTH] = 1 << 3; // These defaults were found using After Burner Climax (which never set fog mode despite using fog input) - m_fog_equation = rsx::fog_mode::linear; - m_fog_params_0 = 1.f; - m_fog_params_1 = 1.f; + registers[NV4097_SET_FOG_MODE] = 0x2601; // rsx::fog_mode::linear; + (f32&)registers[NV4097_SET_FOG_PARAMS] = 1.; + (f32&)registers[NV4097_SET_FOG_PARAMS + 1] = 1.; - m_depth_test_enabled = false; - m_depth_func = rsx::comparison_function::less; - m_depth_write_enabled = true; + registers[NV4097_SET_DEPTH_FUNC] = CELL_GCM_LESS; + registers[NV4097_SET_DEPTH_MASK] = CELL_GCM_TRUE; + (f32&)registers[NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR] = 0.f; + (f32&)registers[NV4097_SET_POLYGON_OFFSET_BIAS] = 0.f; +// registers[NV4097_SET_FRONT_POLYGON_MODE] = CELL_GCM_POLYGON_MODE_FILL; +// registers[NV4097_SET_BACK_POLYGON_MODE] = CELL_GCM_POLYGON_MODE_FILL; + registers[NV4097_SET_CULL_FACE] = CELL_GCM_BACK; + registers[NV4097_SET_FRONT_FACE] = CELL_GCM_CCW; + registers[NV4097_SET_RESTART_INDEX] = -1; + registers[NV4097_SET_CONTEXT_DMA_REPORT] = CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT; - m_poly_offset_scale = 0.f; - m_poly_offset_bias = 0.f; - m_front_polygon_mode = rsx::polygon_mode::fill; - m_back_polygon_mode = rsx::polygon_mode::fill; + registers[NV4097_SET_CLEAR_RECT_HORIZONTAL] = (4096 << 16) | 0; + registers[NV4097_SET_CLEAR_RECT_VERTICAL] = (4096 << 16) | 0; - m_cull_face_enabled = false; - m_cull_face_mode = rsx::cull_face::back; - m_front_face_mode = rsx::front_face::ccw; - m_restart_index_enabled = false; - m_restart_index = -1; + registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffffff; - m_clear_rect_origin_x = 0; - m_clear_rect_origin_y = 0; - m_clear_rect_width = 4096; - m_clear_rect_height = 4096; - - m_z_clear_value = -1; - m_stencil_clear_value = -1; - - m_context_dma_report = rsx::blit_engine::context_dma::to_memory_get_report; - m_two_side_light_enabled = true; - m_alpha_func = rsx::comparison_function::always; - - // Reset vertex attrib array - for (int i = 0; i < 16; i++) - { - vertex_arrays_info[i].size = 0; - } - - // Construct Textures - for (int i = 0; i < 16; i++) - { - fragment_textures[i].init(i); - } - - for (int i = 0; i < 4; i++) - { - vertex_textures[i].init(i); - } + std::for_each(vertex_arrays_info.begin(), vertex_arrays_info.end(), [](auto &info) { info.size = 0; }); + std::for_each(fragment_textures.begin(), fragment_textures.end(), [](auto &tex) { tex.init(); }); + std::for_each(vertex_textures.begin(), vertex_textures.end(), [](auto &tex) { tex.init(); }); } -namespace -{ - template - auto create_commit_functions_table(const std::integer_sequence &) - { - return std::unordered_map{ {opcode, commit}... }; - } - - auto reg_decoder = create_commit_functions_table(opcode_list); -} - void rsx_state::decode(u32 reg, u32 value) { - const auto &It = reg_decoder.find(reg); - if (It != reg_decoder.end()) - (It->second)(*this, value); - else - registers[reg] = value; + registers[reg] = value; } struct __rsx_methods_t @@ -925,7 +978,16 @@ namespace 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(); diff --git a/rpcs3/Emu/RSX/rsx_methods.h b/rpcs3/Emu/RSX/rsx_methods.h index b27c733091..82e76ceddd 100644 --- a/rpcs3/Emu/RSX/rsx_methods.h +++ b/rpcs3/Emu/RSX/rsx_methods.h @@ -4,6 +4,7 @@ #include #include "GCM.h" +#include "rsx_decode.h" #include "RSXTexture.h" #include "rsx_vertex_data.h" #include "Utilities/geometry.h" @@ -76,6 +77,16 @@ namespace rsx private: std::array registers; + template + using decoded_type = typename registers_decoder::decoded_type; + + template + decoded_type decode() const + { + u32 register_value = registers[opcode]; + return decoded_type(register_value); + } + public: std::array fragment_textures; std::array vertex_textures; @@ -111,1176 +122,958 @@ namespace rsx void reset(); - u16 m_viewport_origin_x; - u16 m_viewport_origin_y; - - u16 m_viewport_width; - u16 m_viewport_height; - - u16 m_scissor_origin_x; - u16 m_scissor_origin_y; - - u16 m_scissor_width; - u16 m_scissor_height; - - u16 m_clear_rect_origin_x; - u16 m_clear_rect_origin_y; - u16 m_clear_rect_width; - u16 m_clear_rect_height; - - window_origin m_shader_window_origin : 1; - window_pixel_center m_shader_window_pixel : 1; - u16 m_shader_window_height : 12; - - u16 m_shader_window_offset_x; - u16 m_shader_window_offset_y; - - bool m_dither_enabled : 1; - bool m_line_smooth_enabled : 1; - bool m_poly_offset_point_enabled : 1; - bool m_offset_line_enabled : 1; - bool m_poly_offset_fill_enabled : 1; - bool m_poly_smooth_enabled : 1; - bool m_cull_face_enabled : 1; - bool m_two_sided_stencil_test_enabled : 1; - bool m_color_mask_b : 1; - bool m_color_mask_g : 1; - bool m_color_mask_r : 1; - bool m_color_mask_a : 1; - - rsx::shading_mode m_shading_mode : 1; - - rsx::polygon_mode m_front_polygon_mode : 2; - rsx::polygon_mode m_back_polygon_mode : 2; - - bool m_alpha_test_enabled : 1; - u8 m_alpha_ref; - comparison_function m_alpha_func : 3; - - bool m_restart_index_enabled : 1; - u32 m_restart_index; - - u8 m_stencil_clear_value; - u32 m_z_clear_value : 24; - - fog_mode m_fog_equation : 3; - f32 m_fog_params_0; - f32 m_fog_params_1; - - u8 m_index_array_location : 4; - rsx::index_array_type m_index_type : 1; - u32 m_index_array_address; - - u8 m_clear_color_b; - u8 m_clear_color_r; - u8 m_clear_color_g; - u8 m_clear_color_a; - - f32 m_poly_offset_scale; - f32 m_poly_offset_bias; - - bool m_depth_bounds_test_enabled : 1; - bool m_depth_test_enabled : 1; - bool m_depth_write_enabled : 1; - comparison_function m_depth_func : 3; - f32 m_depth_bounds_min; - f32 m_depth_bounds_max; - f32 m_clip_min; - f32 m_clip_max; - - bool m_stencil_test_enabled : 1; - u8 m_stencil_mask; - u8 m_back_stencil_mask; - u8 m_stencil_func_ref; - u8 m_back_stencil_func_ref; - u8 m_stencil_func_mask; - u8 m_back_stencil_func_mask; - comparison_function m_stencil_func : 3; - comparison_function m_back_stencil_func : 3; - stencil_op m_stencil_op_fail : 3; - stencil_op m_stencil_op_zfail : 3; - stencil_op m_stencil_op_zpass : 3; - stencil_op m_back_stencil_op_fail : 3; - stencil_op m_back_stencil_op_zfail : 3; - stencil_op m_back_stencil_op_zpass : 3; - - bool m_blend_enabled : 1; - bool m_blend_enabled_surface_1 : 1; - bool m_blend_enabled_surface_2 : 1; - bool m_blend_enabled_surface_3 : 1; - // Can be interpreted as 4 x 8 or 2 x 16 color - u32 m_blend_color; - u16 m_blend_color_16b_b; - u16 m_blend_color_16b_a; - blend_equation m_blend_equation_rgb : 3; - blend_equation m_blend_equation_a : 3; - blend_factor m_blend_func_sfactor_rgb : 4; - blend_factor m_blend_func_sfactor_a : 4; - blend_factor m_blend_func_dfactor_rgb : 4; - blend_factor m_blend_func_dfactor_a : 4; - - bool m_logic_op_enabled : 1; - logic_op m_logic_operation : 4; - - user_clip_plane_op m_clip_plane_0_enabled : 1; - user_clip_plane_op m_clip_plane_1_enabled : 1; - user_clip_plane_op m_clip_plane_2_enabled : 1; - user_clip_plane_op m_clip_plane_3_enabled : 1; - user_clip_plane_op m_clip_plane_4_enabled : 1; - user_clip_plane_op m_clip_plane_5_enabled : 1; - - front_face m_front_face_mode : 1; - - cull_face m_cull_face_mode : 2; - - f32 m_line_width; - - surface_target m_surface_color_target : 3; - - u16 m_surface_clip_origin_x; - u16 m_surface_clip_width; - u16 m_surface_clip_origin_y; - u16 m_surface_clip_height; - - u32 m_surface_a_offset; - u32 m_surface_a_pitch; - u32 m_surface_a_dma; - u32 m_surface_b_offset; - u32 m_surface_b_pitch; - u32 m_surface_b_dma; - u32 m_surface_c_offset; - u32 m_surface_c_pitch; - u32 m_surface_c_dma; - u32 m_surface_d_offset; - u32 m_surface_d_pitch; - u32 m_surface_d_dma; - u32 m_surface_z_offset; - u32 m_surface_z_pitch; - u32 m_surface_z_dma; - - f32 m_viewport_scale_x; - f32 m_viewport_scale_y; - f32 m_viewport_scale_z; - f32 m_viewport_scale_w; - f32 m_viewport_offset_x; - f32 m_viewport_offset_y; - f32 m_viewport_offset_z; - f32 m_viewport_offset_w; - - bool m_two_side_light_enabled : 1; - - u16 m_vertex_attrib_input_mask; - u16 m_frequency_divider_operation_mask; - u32 m_vertex_attrib_output_mask; - - // Quite opaque - u32 m_shader_control; - - surface_color_format m_surface_color : 4; - surface_depth_format m_surface_depth_format : 1; - surface_antialiasing m_surface_antialias : 2; - u8 m_surface_log2_height; - u8 m_surface_log2_width; - - bool m_msaa_enabled : 1; - bool m_msaa_alpha_to_coverage : 1; - bool m_msaa_alpha_to_one : 1; - u16 m_msaa_sample_mask; - - u32 m_vertex_data_base_offset; - u32 m_vertex_data_base_index; - u32 m_shader_program_address; - u32 m_transform_program_start; - - primitive_type m_primitive_type : 4; - u32 m_semaphore_offset_406e; - u32 m_semaphore_offset_4097; - - - u32 m_transform_constant_file_pointer; - - blit_engine::context_dma m_context_dma_report : 1; - blit_engine::transfer_operation m_blit_engine_operation : 3; - u16 m_blit_engine_clip_x; - u16 m_blit_engine_clip_y; - u16 m_blit_engine_width; - u16 m_blit_engine_height; - u16 m_blit_engine_output_x; - u16 m_blit_engine_output_y; - u16 m_blit_engine_output_width; - u16 m_blit_engine_output_height; - u16 m_blit_engine_input_width; - u16 m_blit_engine_input_height; - u16 m_blit_engine_input_pitch; - blit_engine::transfer_origin m_blit_engine_input_origin : 1; - blit_engine::transfer_interpolator m_blit_engine_input_inter : 1; - blit_engine::transfer_source_format m_blit_engine_src_color_format : 4; - u16 m_blit_engine_in_x; - u16 m_blit_engine_in_y; - u32 m_blit_engine_input_offset; - u32 m_blit_engine_input_location; - blit_engine::context_surface m_blit_engine_context_surface : 1; - u32 m_blit_engine_output_location_nv3062; - blit_engine::transfer_destination_format m_blit_engine_nv3062_color_format : 2; - u32 m_blit_engine_output_offset_nv3062; - u16 m_blit_engine_output_alignement_nv3062; - u16 m_blit_engine_output_pitch_nv3062; - u32 m_blit_engine_nv309E_location; - u32 m_blit_engine_nv309E_offset; - blit_engine::transfer_destination_format m_blit_engine_output_format_nv309E : 2; - u32 m_blit_engine_ds_dx; - u32 m_blit_engine_dt_dy; - u8 m_nv309e_sw_width_log2; - u8 m_nv309e_sw_height_log2; - u32 m_nv0039_input_pitch; - u32 m_nv0039_output_pitch; - u32 m_nv0039_line_length; - u32 m_nv0039_line_count; - u8 m_nv0039_input_format; - u8 m_nv0039_output_format; - u32 m_nv0039_output_offset; - u32 m_nv0039_output_location; - u32 m_nv0039_input_offset; - u32 m_nv0039_input_location; - u16 m_nv308a_x; - u16 m_nv308a_y; - u16 viewport_width() const { - return m_viewport_width; + return decode().width(); } u16 viewport_origin_x() const { - return m_viewport_origin_x; + return decode().origin_x(); } u16 viewport_height() const { - return m_viewport_height; + return decode().height(); } u16 viewport_origin_y() const { - return m_viewport_origin_y; + return decode().origin_y(); } u16 scissor_origin_x() const { - return m_scissor_origin_x; + return decode().origin_x(); } u16 scissor_width() const { - return m_scissor_width; + return decode().width(); } u16 scissor_origin_y() const { - return m_scissor_origin_y; + return decode().origin_y(); } u16 scissor_height() const { - return m_scissor_height; + return decode().height(); } window_origin shader_window_origin() const { - return m_shader_window_origin; + return decode().window_shader_origin(); } window_pixel_center shader_window_pixel() const { - return m_shader_window_pixel; + return decode().window_shader_pixel_center(); } u16 shader_window_height() const { - return m_shader_window_height; + return decode().window_shader_height(); } u16 shader_window_offset_x() const { - return m_shader_window_offset_x; + return decode().window_offset_x(); } u16 shader_window_offset_y() const { - return m_shader_window_offset_y; + return decode().window_offset_y(); } bool depth_test_enabled() const { - return m_depth_test_enabled; + return decode().depth_test_enabled(); } bool depth_write_enabled() const { - return m_depth_write_enabled; + return decode().depth_write_enabled(); } bool alpha_test_enabled() const { - return m_alpha_test_enabled; + return decode().alpha_test_enabled(); } bool stencil_test_enabled() const { - return m_stencil_test_enabled; + return decode().stencil_test_enabled(); } bool restart_index_enabled() const { - return m_restart_index_enabled; + return decode().restart_index_enabled(); } u32 restart_index() const { - return m_restart_index; + return decode().restart_index(); } u32 z_clear_value() const { - return m_z_clear_value; + return decode().clear_z(); } u8 stencil_clear_value() const { - return m_stencil_clear_value; + return decode().clear_stencil(); } f32 fog_params_0() const { - return m_fog_params_0; + return decode().fog_param_0(); } f32 fog_params_1() const { - return m_fog_params_1; + return decode().fog_param_1(); } u8 index_array_location() const { - return m_index_array_location; + return decode().index_dma(); } rsx::index_array_type index_type() const { - return m_index_type; + return decode().type(); } bool color_mask_b() const { - return m_color_mask_b; + return decode().color_b(); } bool color_mask_g() const { - return m_color_mask_g; + return decode().color_g(); } bool color_mask_r() const { - return m_color_mask_r; + return decode().color_r(); } bool color_mask_a() const { - return m_color_mask_a; + return decode().color_a(); } u8 clear_color_b() const { - return m_clear_color_b; + return decode().blue(); } u8 clear_color_r() const { - return m_clear_color_r; + return decode().red(); } u8 clear_color_g() const { - return m_clear_color_g; + return decode().green(); } u8 clear_color_a() const { - return m_clear_color_a; + return decode().alpha(); } bool depth_bounds_test_enabled() const { - return m_depth_bounds_test_enabled; + return decode().depth_bound_enabled(); } f32 depth_bounds_min() const { - return m_depth_bounds_min; + return decode().depth_bound_min(); } f32 depth_bounds_max() const { - return m_depth_bounds_max; + return decode().depth_bound_max(); } f32 clip_min() const { - return m_clip_min; + return decode().clip_min(); } f32 clip_max() const { - return m_clip_max; + return decode().clip_max(); } bool logic_op_enabled() const { - return m_logic_op_enabled; + return decode().logic_op_enabled(); } u8 stencil_mask() const { - return m_stencil_mask; + return decode().stencil_mask(); } u8 back_stencil_mask() const { - return m_back_stencil_mask; + return decode().back_stencil_mask(); } bool dither_enabled() const { - return m_dither_enabled; + return decode().dither_enabled(); } bool blend_enabled() const { - return m_blend_enabled; + return decode().blend_enabled(); } bool blend_enabled_surface_1() const { - return m_blend_enabled_surface_1; + return decode().blend_surface_b(); } bool blend_enabled_surface_2() const { - return m_blend_enabled_surface_2; + return decode().blend_surface_c(); } bool blend_enabled_surface_3() const { - return m_blend_enabled_surface_3; + return decode().blend_surface_d(); } bool line_smooth_enabled() const { - return m_line_smooth_enabled; + return decode().line_smooth_enabled(); } bool poly_offset_point_enabled() const { - return m_poly_offset_point_enabled; + return decode().poly_offset_point_enabled(); } bool poly_offset_line_enabled() const { - return m_offset_line_enabled; + return decode().poly_offset_line_enabled(); } bool poly_offset_fill_enabled() const { - return m_poly_offset_fill_enabled; + return decode().poly_offset_fill_enabled(); } f32 poly_offset_scale() const { - return m_poly_offset_scale; + return decode().polygon_offset_scale_factor(); } f32 poly_offset_bias() const { - return m_poly_offset_bias; + return decode().polygon_offset_scale_bias(); } bool cull_face_enabled() const { - return m_cull_face_enabled; + return decode().cull_face_enabled(); } bool poly_smooth_enabled() const { - return m_poly_smooth_enabled; + return decode().poly_smooth_enabled(); } bool two_sided_stencil_test_enabled() const { - return m_two_sided_stencil_test_enabled; + return decode().two_sided_stencil_test_enabled(); } comparison_function depth_func() const { - return m_depth_func; + return decode().depth_func(); } comparison_function stencil_func() const { - return m_stencil_func; + return decode().stencil_func(); } comparison_function back_stencil_func() const { - return m_back_stencil_func; + return decode().back_stencil_func(); } u8 stencil_func_ref() const { - return m_stencil_func_ref; + return decode().stencil_func_ref(); } u8 back_stencil_func_ref() const { - return m_back_stencil_func_ref; + return decode().back_stencil_func_ref(); } u8 stencil_func_mask() const { - return m_stencil_func_mask; + return decode().stencil_func_mask(); } u8 back_stencil_func_mask() const { - return m_back_stencil_func_mask; + return decode().back_stencil_func_mask(); } stencil_op stencil_op_fail() const { - return m_stencil_op_fail; + return decode().fail(); } stencil_op stencil_op_zfail() const { - return m_stencil_op_zfail; + return decode().zfail(); } stencil_op stencil_op_zpass() const { - return m_stencil_op_zpass; + return decode().zpass(); } stencil_op back_stencil_op_fail() const { - return m_back_stencil_op_fail; + return decode().back_fail(); } rsx::stencil_op back_stencil_op_zfail() const { - return m_back_stencil_op_zfail; + return decode().back_zfail(); } rsx::stencil_op back_stencil_op_zpass() const { - return m_back_stencil_op_zpass; + return decode().back_zpass(); } u8 blend_color_8b_r() const { - return m_blend_color & 0xff; + return decode().red8(); } u8 blend_color_8b_g() const { - return (m_blend_color >> 8) & 0xff; + return decode().green8(); } u8 blend_color_8b_b() const { - return (m_blend_color >> 16) & 0xff; + return decode().blue8(); } u8 blend_color_8b_a() const { - return (m_blend_color >> 24) & 0xff; + return decode().alpha8(); } u16 blend_color_16b_r() const { - return m_blend_color & 0xffff; + return decode().red16(); } u16 blend_color_16b_g() const { - return (m_blend_color >> 16) & 0xffff; + return decode().green16(); } u16 blend_color_16b_b() const { - return m_blend_color_16b_b; + return decode().blue(); } u16 blend_color_16b_a() const { - return m_blend_color_16b_a; + return decode().alpha(); } blend_equation blend_equation_rgb() const { - return m_blend_equation_rgb; + return decode().blend_rgb(); } blend_equation blend_equation_a() const { - return m_blend_equation_a; + return decode().blend_a(); } blend_factor blend_func_sfactor_rgb() const { - return m_blend_func_sfactor_rgb; + return decode().src_blend_rgb(); } blend_factor blend_func_sfactor_a() const { - return m_blend_func_sfactor_a; + return decode().src_blend_a(); } blend_factor blend_func_dfactor_rgb() const { - return m_blend_func_dfactor_rgb; + return decode().dst_blend_rgb(); } blend_factor blend_func_dfactor_a() const { - return m_blend_func_dfactor_a; + return decode().dst_blend_a(); } logic_op logic_operation() const { - return m_logic_operation; + return decode().logic_operation(); } user_clip_plane_op clip_plane_0_enabled() const { - return m_clip_plane_0_enabled; + return decode().clip_plane0(); } user_clip_plane_op clip_plane_1_enabled() const { - return m_clip_plane_1_enabled; + return decode().clip_plane1(); } user_clip_plane_op clip_plane_2_enabled() const { - return m_clip_plane_2_enabled; + return decode().clip_plane2(); } user_clip_plane_op clip_plane_3_enabled() const { - return m_clip_plane_3_enabled; + return decode().clip_plane3(); } user_clip_plane_op clip_plane_4_enabled() const { - return m_clip_plane_4_enabled; + return decode().clip_plane4(); } user_clip_plane_op clip_plane_5_enabled() const { - return m_clip_plane_5_enabled; + return decode().clip_plane5(); } front_face front_face_mode() const { - return m_front_face_mode; + return decode().front_face_mode(); } cull_face cull_face_mode() const { - return m_cull_face_mode; + return decode().cull_face_mode(); } f32 line_width() const { - return m_line_width; + return decode().line_width(); } u8 alpha_ref() const { - return m_alpha_ref; + return decode().alpha_ref(); } surface_target surface_color_target() { - return m_surface_color_target; + return decode().target(); } u16 surface_clip_origin_x() const { - return m_surface_clip_origin_x; + return decode().origin_x(); } u16 surface_clip_width() const { - return m_surface_clip_width; + return decode().width(); } u16 surface_clip_origin_y() const { - return m_surface_clip_origin_y; + return decode().origin_y(); } u16 surface_clip_height() const { - return m_surface_clip_height; + return decode().height(); } u32 surface_a_offset() const { - return m_surface_a_offset; + return decode().surface_a_offset(); } u32 surface_b_offset() const { - return m_surface_b_offset; + return decode().surface_b_offset(); } u32 surface_c_offset() const { - return m_surface_c_offset; + return decode().surface_c_offset(); } u32 surface_d_offset() const { - return m_surface_d_offset; + return decode().surface_d_offset(); } u32 surface_a_pitch() const { - return m_surface_a_pitch; + return decode().surface_a_pitch(); } u32 surface_b_pitch() const { - return m_surface_b_pitch; + return decode().surface_b_pitch(); } u32 surface_c_pitch() const { - return m_surface_c_pitch; + return decode().surface_c_pitch(); } u32 surface_d_pitch() const { - return m_surface_d_pitch; + return decode().surface_d_pitch(); } u32 surface_a_dma() const { - return m_surface_a_dma; + return decode().dma_surface_a(); } u32 surface_b_dma() const { - return m_surface_b_dma; + return decode().dma_surface_b(); } u32 surface_c_dma() const { - return m_surface_c_dma; + return decode().dma_surface_c(); } u32 surface_d_dma() const { - return m_surface_d_dma; + return decode().dma_surface_d(); } u32 surface_z_offset() const { - return m_surface_z_offset; + return decode().surface_z_offset(); } u32 surface_z_pitch() const { - return m_surface_z_pitch; + return decode().surface_z_pitch(); } u32 surface_z_dma() const { - return m_surface_z_dma; + return decode().dma_surface_z(); } f32 viewport_scale_x() const { - return m_viewport_scale_x; + return decode().viewport_scale_x(); } f32 viewport_scale_y() const { - return m_viewport_scale_y; + return decode().viewport_scale_y(); } f32 viewport_scale_z() const { - return m_viewport_scale_z; + return decode().viewport_scale_z(); } f32 viewport_scale_w() const { - return m_viewport_scale_w; + return decode().viewport_scale_w(); } f32 viewport_offset_x() const { - return m_viewport_offset_x; + return decode().viewport_offset_x(); } f32 viewport_offset_y() const { - return m_viewport_offset_y; + return decode().viewport_offset_y(); } f32 viewport_offset_z() const { - return m_viewport_offset_z; + return decode().viewport_offset_z(); } f32 viewport_offset_w() const { - return m_viewport_offset_w; + return decode().viewport_offset_w(); } bool two_side_light_en() const { - return m_two_side_light_enabled; + return decode().two_sided_lighting_enabled(); } fog_mode fog_equation() const { - return m_fog_equation; + return decode().fog_equation(); } comparison_function alpha_func() const { - return m_alpha_func; + return decode().alpha_func(); } u16 vertex_attrib_input_mask() const { - return m_vertex_attrib_input_mask; + return decode().mask(); } u16 frequency_divider_operation_mask() const { - return m_frequency_divider_operation_mask; + return decode().frequency_divider_operation_mask(); } u32 vertex_attrib_output_mask() const { - return m_vertex_attrib_output_mask; + return decode().output_mask(); } u32 shader_control() const { - return m_shader_control; + return decode().shader_ctrl(); } surface_color_format surface_color() const { - return m_surface_color; + return decode().color_fmt(); } surface_depth_format surface_depth_fmt() const { - return m_surface_depth_format; + return decode().depth_fmt(); } surface_antialiasing surface_antialias() const { - return m_surface_antialias; + return decode().antialias(); } u8 surface_log2_height() const { - return m_surface_log2_height; + return decode().log2height(); } u8 surface_log2_width() const { - return m_surface_log2_width; + return decode().log2width(); } u32 vertex_data_base_offset() const { - return m_vertex_data_base_offset; + return decode().vertex_data_base_offset(); } u32 index_array_address() const { - return m_index_array_address; + return decode().index_array_offset(); } u32 vertex_data_base_index() const { - return m_vertex_data_base_index; + return decode().vertex_data_base_index(); } u32 shader_program_address() const { - return m_shader_program_address; + return decode().shader_program_address(); } u32 transform_program_start() const { - return m_transform_program_start; + return decode().transform_program_start(); } primitive_type primitive_mode() const { - return m_primitive_type; + return decode().primitive(); } u32 semaphore_offset_406e() const { - return m_semaphore_offset_406e; + return decode().semaphore_offset(); } u32 semaphore_offset_4097() const { - return m_semaphore_offset_4097; + return decode().semaphore_offset(); } blit_engine::context_dma context_dma_report() const { - return m_context_dma_report; + return decode().context_dma_report(); } blit_engine::transfer_operation blit_engine_operation() const { - return m_blit_engine_operation; + return decode().transfer_op(); } /// TODO: find the purpose vs in/out equivalents u16 blit_engine_clip_x() const { - return m_blit_engine_clip_x; + return decode().clip_x(); } u16 blit_engine_clip_y() const { - return m_blit_engine_clip_y; + return decode().clip_y(); } u16 blit_engine_clip_width() const { - return m_blit_engine_width; + return decode().clip_width(); } u16 blit_engine_clip_height() const { - return m_blit_engine_height; + return decode().clip_height(); } u16 blit_engine_output_x() const { - return m_blit_engine_output_x; + return decode().x(); } u16 blit_engine_output_y() const { - return m_blit_engine_output_y; + return decode().y(); } u16 blit_engine_output_width() const { - return m_blit_engine_output_width; + return decode().width(); } u16 blit_engine_output_height() const { - return m_blit_engine_output_height; + return decode().height(); } // there is no x/y ? u16 blit_engine_input_width() const { - return m_blit_engine_input_width; + return decode().width(); } u16 blit_engine_input_height() const { - return m_blit_engine_input_height; + return decode().height(); } u16 blit_engine_input_pitch() const { - return m_blit_engine_input_pitch; + return decode().format(); } blit_engine::transfer_origin blit_engine_input_origin() const { - return m_blit_engine_input_origin; + return decode().transfer_origin(); } blit_engine::transfer_interpolator blit_engine_input_inter() const { - return m_blit_engine_input_inter; + return decode().transfer_interpolator(); } blit_engine::transfer_source_format blit_engine_src_color_format() const { - return m_blit_engine_src_color_format; + return decode().transfer_source_fmt(); } // ??? f32 blit_engine_in_x() const { - return m_blit_engine_in_x / 16.f; + return decode().x(); } // ??? f32 blit_engine_in_y() const { - return m_blit_engine_in_y / 16.f; + return decode().y(); } u32 blit_engine_input_offset() const { - return m_blit_engine_input_offset; + return decode().input_offset(); } u32 blit_engine_input_location() const { - return m_blit_engine_input_location; + return decode().context_dma(); } blit_engine::context_surface blit_engine_context_surface() const { - return m_blit_engine_context_surface; + return decode().ctx_surface(); } u32 blit_engine_output_location_nv3062() const { - return m_blit_engine_output_location_nv3062; + return decode().output_dma(); } u32 blit_engine_output_offset_nv3062() const { - return m_blit_engine_output_offset_nv3062; + return decode().output_offset(); } blit_engine::transfer_destination_format blit_engine_nv3062_color_format() const { - return m_blit_engine_nv3062_color_format; + return decode().transfer_dest_fmt(); } u16 blit_engine_output_alignment_nv3062() const { - return m_blit_engine_output_alignement_nv3062; + return decode().alignment(); } u16 blit_engine_output_pitch_nv3062() const { - return m_blit_engine_output_pitch_nv3062; + return decode().pitch(); } u32 blit_engine_nv309E_location() const { - return m_blit_engine_nv309E_location; + return decode().context_dma(); } u32 blit_engine_nv309E_offset() const { - return m_blit_engine_nv309E_offset; + return decode().offset(); } blit_engine::transfer_destination_format blit_engine_output_format_nv309E() const { - return m_blit_engine_output_format_nv309E; + return decode().format(); } u32 blit_engine_ds_dx() const { - return m_blit_engine_ds_dx; + return decode().ds_dx(); } u32 blit_engine_dt_dy() const { - return m_blit_engine_dt_dy; + return decode().dt_dy(); } u8 nv309e_sw_width_log2() const { - return m_nv309e_sw_width_log2; + return decode().sw_width_log2(); } u8 nv309e_sw_height_log2() const { - return m_nv309e_sw_height_log2; + return decode().sw_height_log2(); } u32 nv0039_input_pitch() const { - return m_nv0039_input_pitch; + return decode().input_pitch(); } u32 nv0039_output_pitch() const { - return m_nv0039_output_pitch; + return decode().output_pitch(); } u32 nv0039_line_length() const { - return m_nv0039_line_length; + return decode().input_line_length(); } u32 nv0039_line_count() const { - return m_nv0039_line_count; + return decode().line_count(); } u8 nv0039_output_format() const { - return m_nv0039_output_format; + return decode().output_format(); } u8 nv0039_input_format() const { - return m_nv0039_input_format; + return decode().input_format(); } u32 nv0039_output_offset() const { - return m_nv0039_output_offset; + return decode().output_offset(); } u32 nv0039_output_location() { - return m_nv0039_output_location; + return decode().output_dma(); } u32 nv0039_input_offset() const { - return m_nv0039_input_offset; + return decode().input_offset(); } u32 nv0039_input_location() const { - return m_nv0039_input_location; + return decode().input_dma(); } u16 nv308a_x() const { - return m_nv308a_x; + return decode().x(); } u16 nv308a_y() const { - return m_nv308a_y; + return decode().y(); + } + + void commit_4_transform_program_instructions(u32 index) + { + u32& load = registers[NV4097_SET_TRANSFORM_PROGRAM_LOAD]; + + transform_program[load * 4] = registers[NV4097_SET_TRANSFORM_PROGRAM + index * 4]; + transform_program[load * 4 + 1] = registers[NV4097_SET_TRANSFORM_PROGRAM + index * 4 + 1]; + transform_program[load * 4 + 2] = registers[NV4097_SET_TRANSFORM_PROGRAM + index * 4 + 2]; + transform_program[load * 4 + 3] = registers[NV4097_SET_TRANSFORM_PROGRAM + index * 4 + 3]; + load++; + } + + u32 transform_constant_load() + { + return decode().transform_constant_load(); } }; using rsx_method_t = void(*)(class thread*, u32); extern rsx_state method_registers; - extern rsx_method_t methods[0x10000 >> 2]; + extern std::unordered_map methods; } diff --git a/rpcs3/Emu/RSX/rsx_vertex_data.h b/rpcs3/Emu/RSX/rsx_vertex_data.h index 62598327cc..82a64236b8 100644 --- a/rpcs3/Emu/RSX/rsx_vertex_data.h +++ b/rpcs3/Emu/RSX/rsx_vertex_data.h @@ -8,17 +8,20 @@ namespace rsx struct data_array_format_info { +private: + u32& m_offset_register; +public: u16 frequency = 0; u8 stride = 0; u8 size = 0; vertex_base_type type = vertex_base_type::f; - u32 m_offset; - data_array_format_info() {} + data_array_format_info(int id, std::array ®isters) + : m_offset_register(registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + id]) {} u32 offset() const { - return m_offset; + return m_offset_register; } };