diff --git a/rpcs3/Emu/RSX/GCM.cpp b/rpcs3/Emu/RSX/GCM.cpp index cd551e15b7..84dab2cc5f 100644 --- a/rpcs3/Emu/RSX/GCM.cpp +++ b/rpcs3/Emu/RSX/GCM.cpp @@ -1,9 +1,10 @@ #include "stdafx.h" #include "GCM.h" +#include "rsx_decode.h" namespace { - const std::unordered_map methods = + const std::unordered_map methods_name = { { NV4097_NO_OPERATION, "NV4097_NO_OPERATION" }, { NV4097_NOTIFY, "NV4097_NOTIFY" }, @@ -748,6 +749,7 @@ rsx::primitive_type rsx::to_primitive_type(u8 in) { switch (in) { + case 0: return rsx::primitive_type::invalid; case 1: return rsx::primitive_type::points; case 2: return rsx::primitive_type::lines; case 3: return rsx::primitive_type::line_loop; @@ -841,6 +843,375 @@ rsx::texture_dimension rsx::to_texture_dimension(u8 in) throw EXCEPTION("Wrong texture dimension %d", in); } +namespace rsx +{ +std::string print_boolean(bool b) +{ + switch (b) + { + case false: return "disabled"; + default: return "enabled"; + } +} + +std::string print_comparaison_function(comparaison_function f) +{ + switch (f) + { + case comparaison_function::never: return "Never"; + case comparaison_function::less: return "Less"; + case comparaison_function::equal: return "Equal"; + case comparaison_function::less_or_equal: return "Less_equal"; + case comparaison_function::greater: return "Greater"; + case comparaison_function::not_equal: return "Not_equal"; + case comparaison_function::greater_or_equal: return "Greater_equal"; + case comparaison_function::always: return "Always"; + } + throw; +} + +std::string print_stencil_op(stencil_op op) +{ + switch (op) + { + case stencil_op::keep: return "Keep"; + case stencil_op::zero: return "Zero"; + case stencil_op::replace: return "Replace"; + case stencil_op::incr: return "Incr"; + case stencil_op::decr: return "Decr"; + case stencil_op::incr_wrap: return "Incr_wrap"; + case stencil_op::decr_wrap: return "Decr_wrap"; + } + throw; +} + +std::string print_fog_mode(fog_mode op) +{ + switch (op) + { + case fog_mode::exponential: return "exponential"; + case fog_mode::exponential2: return "exponential2"; + case fog_mode::exponential2_abs: return "exponential2(abs)"; + case fog_mode::exponential_abs: return "exponential(abs)"; + case fog_mode::linear: return "linear"; + case fog_mode::linear_abs: return "linear(abs)"; + } + throw; +} + +std::string print_logic_op(logic_op op) +{ + switch (op) + { + case logic_op::logic_clear: return "Clear"; + case logic_op::logic_and: return "And"; + case logic_op::logic_and_reverse: return "And_reverse"; + case logic_op::logic_copy: return "Copy"; + case logic_op::logic_and_inverted: return "And_inverted"; + case logic_op::logic_noop: return "Noop"; + case logic_op::logic_xor: return "Xor"; + case logic_op::logic_or: return "Or"; + case logic_op::logic_nor: return "Nor"; + case logic_op::logic_equiv: return "Equiv"; + case logic_op::logic_invert: return "Invert"; + case logic_op::logic_or_reverse: return "Or_reverse"; + case logic_op::logic_copy_inverted: return "Copy_inverted"; + case logic_op::logic_or_inverted: return "Or_inverted"; + case logic_op::logic_nand: return "Nand"; + } + throw; +} + +std::string print_front_face(front_face op) +{ + switch (op) + { + case front_face::ccw: return "counter clock wise"; + case front_face::cw: return "clock wise"; + } + throw; +} + +std::string print_cull_face(cull_face op) +{ + switch (op) + { + case cull_face::back: return "back"; + case cull_face::front: return "front"; + case cull_face::front_and_back: return "front and back"; + } + throw; +} + +std::string print_surface_target(surface_target target) +{ + switch (target) + { + case surface_target::none: return "none"; + case surface_target::surface_a: return "surface A"; + case surface_target::surface_b: return "surface B"; + case surface_target::surfaces_a_b: return "surfaces A and B"; + case surface_target::surfaces_a_b_c: return "surfaces A, B and C"; + case surface_target::surfaces_a_b_c_d: return "surfaces A,B, C and D"; + } + throw; +} + +std::string print_primitive_mode(primitive_type draw_mode) +{ + switch (draw_mode) + { + case primitive_type::invalid: return ""; + case primitive_type::points: return "Points"; + case primitive_type::lines: return "Lines"; + case primitive_type::line_loop: return "Line_loop"; + case primitive_type::line_strip: return "Line_strip"; + case primitive_type::triangles: return "Triangles"; + case primitive_type::triangle_strip: return "Triangle_strip"; + case primitive_type::triangle_fan: return "Triangle_fan"; + case primitive_type::quads: return "Quads"; + case primitive_type::quad_strip: return "Quad_strip"; + case primitive_type::polygon: return "Polygon"; + } + throw; +} + +std::string print_transfer_operation(blit_engine::transfer_operation op) +{ + switch (op) + { + case blit_engine::transfer_operation::blend_and: return "blend and"; + case blit_engine::transfer_operation::blend_premult: return "blend premult"; + case blit_engine::transfer_operation::rop_and: return "rop and"; + case blit_engine::transfer_operation::srccopy: return "srccopy"; + case blit_engine::transfer_operation::srccopy_and: return "srccopy_and"; + case blit_engine::transfer_operation::srccopy_premult: return "srccopy_premult"; + } + throw; +} + +std::string print_transfer_source_format(blit_engine::transfer_source_format op) +{ + switch (op) + { + case blit_engine::transfer_source_format::a1r5g5b5: return "a1r5g5b5"; + case blit_engine::transfer_source_format::a8b8g8r8: return "a8b8g8r8"; + case blit_engine::transfer_source_format::a8r8g8b8: return "a8r8g8b8"; + case blit_engine::transfer_source_format::ay8: return "ay8"; + case blit_engine::transfer_source_format::cr8yb8cb8ya8: return "cr8yb8cb8ya8"; + case blit_engine::transfer_source_format::ecr8eyb8ecb8eya8: return "ecr8eyb8ecb8eya8"; + case blit_engine::transfer_source_format::eyb8ecr8eya8ecb8: return "eyb8ecr8eya8ecb8"; + case blit_engine::transfer_source_format::r5g6b5: return "r5g6b5"; + case blit_engine::transfer_source_format::x1r5g5b5: return "x1r5g5b5"; + case blit_engine::transfer_source_format::x8b8g8r8: return "x8b8g8r8"; + case blit_engine::transfer_source_format::x8r8g8b8: return "x8r8g8b8"; + case blit_engine::transfer_source_format::y8: return "y8"; + case blit_engine::transfer_source_format::yb8cr8ya8cb8: return "yb8cr8ya8cb8"; + } + throw; +} + +std::string print_context_surface(blit_engine::context_surface op) +{ + switch (op) + { + case blit_engine::context_surface::surface2d: return "surface 2d"; + case blit_engine::context_surface::swizzle2d: return "swizzle 2d"; + } + throw; +} + +std::string print_transfer_destination_format(blit_engine::transfer_destination_format op) +{ + switch (op) + { + case blit_engine::transfer_destination_format::a8r8g8b8: return "a8r8g8b8"; + case blit_engine::transfer_destination_format::r5g6b5: return "r5g6b5"; + case blit_engine::transfer_destination_format::y32: return "y32"; + } + throw; +} + + +std::string print_blend_op(blend_equation op) +{ + switch (op) + { + case blend_equation::add: return "Add"; + case blend_equation::substract: return "Substract"; + case blend_equation::reverse_substract: return "Reverse_substract"; + case blend_equation::min: return "Min"; + case blend_equation::max: return "Max"; + case blend_equation::add_signed: return "Add_signed"; + case blend_equation::reverse_add_signed: return "Reverse_add_signed"; + case blend_equation::reverse_substract_signed: return "Reverse_substract_signed"; + } + throw; +} + +std::string print_blend_factor(blend_factor factor) +{ + switch (factor) + { + case blend_factor::zero: return "0"; + case blend_factor::one: return "1"; + case blend_factor::src_color: return "src.rgb"; + case blend_factor::one_minus_src_color: return "(1 - src.rgb)"; + case blend_factor::src_alpha: return "src.a"; + case blend_factor::one_minus_src_alpha: return "(1 - src.a)"; + case blend_factor::dst_alpha: return "dst.a"; + case blend_factor::one_minus_dst_alpha: return "(1 - dst.a)"; + case blend_factor::dst_color: return "dst.rgb"; + case blend_factor::one_minus_dst_color: return "(1 - dst.rgb)"; + case blend_factor::src_alpha_saturate: return "sat(src.a)"; + case blend_factor::constant_color: return "const.rgb"; + case blend_factor::one_minus_constant_color: return "(1 - const.rgb)"; + case blend_factor::constant_alpha: return "const.a"; + case blend_factor::one_minus_constant_alpha: return "(1 - const.a)"; + } + throw; +} + +std::string print_origin_mode(window_origin origin) +{ + switch (origin) + { + case window_origin::bottom: return "bottom"; + case window_origin::top: return "top"; + } + throw; +} + +std::string print_pixel_center_mode(window_pixel_center in) +{ + switch (in) + { + case window_pixel_center::half: return "half"; + case window_pixel_center::integer: return "integer"; + } + throw; +} + +std::string print_user_clip_plane_op(user_clip_plane_op op) +{ + switch (op) + { + case user_clip_plane_op::disable: return "disabled"; + case user_clip_plane_op::greather_or_equal: return "greater or equal"; + case user_clip_plane_op::less_than: return "less than"; + } + throw; +} + + + +std::string print_depth_stencil_surface_format(surface_depth_format format) +{ + switch (format) + { + case surface_depth_format::z16: return "CELL_GCM_SURFACE_Z16"; + case surface_depth_format::z24s8: return "CELL_GCM_SURFACE_Z24S8"; + } + throw; +} + +std::string print_surface_antialiasing(surface_antialiasing format) +{ + switch (format) + { + case surface_antialiasing::center_1_sample: return "1 sample centered"; + case surface_antialiasing::diagonal_centered_2_samples: return "2 samples diagonal centered"; + case surface_antialiasing::square_centered_4_samples: return "4 samples square centered"; + case surface_antialiasing::square_rotated_4_samples: return "4 samples diagonal rotated"; + } + throw; +} + +std::string print_surface_color_format(surface_color_format format) +{ + switch (format) + { + case surface_color_format::x1r5g5b5_z1r5g5b5: return "CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5"; + case surface_color_format::x1r5g5b5_o1r5g5b5: return "CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5"; + case surface_color_format::r5g6b5: return "CELL_GCM_SURFACE_R5G6B5"; + case surface_color_format::x8r8g8b8_z8r8g8b8: return "CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8"; + case surface_color_format::x8r8g8b8_o8r8g8b8: return "CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8"; + case surface_color_format::a8r8g8b8: return "CELL_GCM_SURFACE_A8R8G8B8"; + case surface_color_format::b8: return "CELL_GCM_SURFACE_B8"; + case surface_color_format::g8b8: return "CELL_GCM_SURFACE_G8B8"; + case surface_color_format::w16z16y16x16: return "CELL_GCM_SURFACE_F_W16Z16Y16X16"; + case surface_color_format::w32z32y32x32: return "CELL_GCM_SURFACE_F_W32Z32Y32X32"; + case surface_color_format::x32: return "CELL_GCM_SURFACE_F_X32"; + case surface_color_format::x8b8g8r8_z8b8g8r8: return "CELL_GCM_SURFACE_X8B8G8R8_Z8B8G8R8"; + case surface_color_format::x8b8g8r8_o8b8g8r8: return "CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8"; + case surface_color_format::a8b8g8r8: return "CELL_GCM_SURFACE_A8B8G8R8"; + } + throw; +} + +std::string print_index_type(index_array_type arg) +{ + switch (arg) + { + case index_array_type::u16: return "unsigned short"; + case index_array_type::u32: return "unsigned int"; + } + throw; +} + +std::string print_context_dma(blit_engine::context_dma op) +{ + switch (op) + { + case blit_engine::context_dma::report_location_main: return "report location main"; + case blit_engine::context_dma::to_memory_get_report: return "to memory get report"; + } + throw; +} + +std::string print_transfer_origin(blit_engine::transfer_origin op) +{ + switch (op) + { + case blit_engine::transfer_origin::center: return "center"; + case blit_engine::transfer_origin::corner: return "corner"; + } + throw; +} + +std::string print_transfer_interpolator(blit_engine::transfer_interpolator op) +{ + switch (op) + { + case blit_engine::transfer_interpolator::foh: return "foh"; + case blit_engine::transfer_interpolator::zoh: return "zoh"; + } + throw; +} + +std::string print_shading_mode(shading_mode op) +{ + switch (op) + { + case shading_mode::flat: return "flat"; + case shading_mode::smooth: return "smooth"; + } + throw; +} + +std::string print_polygon_mode(polygon_mode op) +{ + switch (op) + { + case polygon_mode::fill: return "fill"; + case polygon_mode::line: return "line"; + case polygon_mode::point: return "point"; + } + throw; +} + +} // end namespace rsx + enum { // Surface Target @@ -993,8 +1364,8 @@ rsx::surface_depth_format rsx::to_surface_depth_format(u8 in) std::string rsx::get_method_name(const u32 id) { - auto found = methods.find(id); - if (found != methods.end()) + auto found = methods_name.find(id); + if (found != methods_name.end()) { return "CELL_GCM_"s + found->second; } @@ -1036,6 +1407,16 @@ rsx::surface_color_format rsx::to_surface_color_format(u8 in) throw EXCEPTION("unknow surface color format %x", in); } +enum +{ + CELL_GCM_KEEP = 0x1E00, + CELL_GCM_REPLACE = 0x1E01, + CELL_GCM_INCR = 0x1E02, + CELL_GCM_DECR = 0x1E03, + CELL_GCM_INCR_WRAP = 0x8507, + CELL_GCM_DECR_WRAP = 0x8508, +}; + rsx::stencil_op rsx::to_stencil_op(u16 in) { switch (in) @@ -1051,6 +1432,18 @@ rsx::stencil_op rsx::to_stencil_op(u16 in) throw EXCEPTION("unknow stencil op %x", in); } +enum +{ + CELL_GCM_FUNC_ADD = 0x8006, + CELL_GCM_MIN = 0x8007, + CELL_GCM_MAX = 0x8008, + CELL_GCM_FUNC_SUBTRACT = 0x800A, + CELL_GCM_FUNC_REVERSE_SUBTRACT = 0x800B, + CELL_GCM_FUNC_REVERSE_SUBTRACT_SIGNED = 0x0000F005, + CELL_GCM_FUNC_ADD_SIGNED = 0x0000F006, + CELL_GCM_FUNC_REVERSE_ADD_SIGNED = 0x0000F007, +}; + rsx::blend_equation rsx::to_blend_equation(u16 in) { switch (in) @@ -1067,6 +1460,23 @@ rsx::blend_equation rsx::to_blend_equation(u16 in) throw EXCEPTION("unknow blend eq %x", in); } +enum +{ + CELL_GCM_SRC_COLOR = 0x0300, + CELL_GCM_ONE_MINUS_SRC_COLOR = 0x0301, + CELL_GCM_SRC_ALPHA = 0x0302, + CELL_GCM_ONE_MINUS_SRC_ALPHA = 0x0303, + CELL_GCM_DST_ALPHA = 0x0304, + CELL_GCM_ONE_MINUS_DST_ALPHA = 0x0305, + CELL_GCM_DST_COLOR = 0x0306, + CELL_GCM_ONE_MINUS_DST_COLOR = 0x0307, + CELL_GCM_SRC_ALPHA_SATURATE = 0x0308, + CELL_GCM_CONSTANT_COLOR = 0x8001, + CELL_GCM_ONE_MINUS_CONSTANT_COLOR = 0x8002, + CELL_GCM_CONSTANT_ALPHA = 0x8003, + CELL_GCM_ONE_MINUS_CONSTANT_ALPHA = 0x8004, +}; + rsx::blend_factor rsx::to_blend_factor(u16 in) { switch (in) @@ -1090,6 +1500,26 @@ rsx::blend_factor rsx::to_blend_factor(u16 in) throw EXCEPTION("unknow blend factor %x", in); } +enum +{ + CELL_GCM_CLEAR = 0x1500, + CELL_GCM_AND = 0x1501, + CELL_GCM_AND_REVERSE = 0x1502, + CELL_GCM_COPY = 0x1503, + CELL_GCM_AND_INVERTED = 0x1504, + CELL_GCM_NOOP = 0x1505, + CELL_GCM_XOR = 0x1506, + CELL_GCM_OR = 0x1507, + CELL_GCM_NOR = 0x1508, + CELL_GCM_EQUIV = 0x1509, + CELL_GCM_INVERT = 0x150A, + CELL_GCM_OR_REVERSE = 0x150B, + CELL_GCM_COPY_INVERTED = 0x150C, + CELL_GCM_OR_INVERTED = 0x150D, + CELL_GCM_NAND = 0x150E, + CELL_GCM_SET = 0x150F, +}; + rsx::logic_op rsx::to_logic_op(u16 in) { switch (in) @@ -1290,106 +1720,44 @@ rsx::user_clip_plane_op rsx::to_user_clip_plane_op(u8 in) throw EXCEPTION("unknow user clip plane %x", in); } +enum +{ + CELL_GCM_FLAT = 0x1D00, + CELL_GCM_SMOOTH = 0x1D01, +}; + +rsx::shading_mode rsx::to_shading_mode(u32 in) +{ + switch (in) + { + case CELL_GCM_FLAT: return rsx::shading_mode::flat; + case CELL_GCM_SMOOTH: return rsx::shading_mode::smooth; + } + throw EXCEPTION("unknow shading mode %x", in); +} + +enum +{ + CELL_GCM_POLYGON_MODE_POINT = 0x1B00, + CELL_GCM_POLYGON_MODE_LINE = 0x1B01, + CELL_GCM_POLYGON_MODE_FILL = 0x1B02, +}; + +rsx::polygon_mode rsx::to_polygon_mode(u32 in) +{ + switch (in) + { + case CELL_GCM_POLYGON_MODE_POINT: return rsx::polygon_mode::point; + case CELL_GCM_POLYGON_MODE_LINE: return rsx::polygon_mode::line; + case CELL_GCM_POLYGON_MODE_FILL: return rsx::polygon_mode::fill; + } + throw EXCEPTION("unknow polygon mode %x", in); +} + // Various parameter pretty printing function namespace { - std::string get_blend_factor(u16 factor) - { - switch (factor) - { - case CELL_GCM_ZERO: return "0"; - case CELL_GCM_ONE: return "1"; - case CELL_GCM_SRC_COLOR: return "src.rgb"; - case CELL_GCM_ONE_MINUS_SRC_COLOR: return "(1 - src.rgb)"; - case CELL_GCM_SRC_ALPHA: return "src.a"; - case CELL_GCM_ONE_MINUS_SRC_ALPHA: return "(1 - src.a)"; - case CELL_GCM_DST_ALPHA: return "dst.a"; - case CELL_GCM_ONE_MINUS_DST_ALPHA: return "(1 - dst.a)"; - case CELL_GCM_DST_COLOR: return "dst.rgb"; - case CELL_GCM_ONE_MINUS_DST_COLOR: return "(1 - dst.rgb)"; - case CELL_GCM_SRC_ALPHA_SATURATE: return "sat(src.a)"; - case CELL_GCM_CONSTANT_COLOR: return "const.rgb"; - case CELL_GCM_ONE_MINUS_CONSTANT_COLOR: return "(1 - const.rgb)"; - case CELL_GCM_CONSTANT_ALPHA: return "const.a"; - case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA: return "(1 - const.a)"; - } - return "Error"; - } - - std::string get_blend_op(u16 op) - { - switch (op) - { - case CELL_GCM_FUNC_ADD: return "Add"; - case CELL_GCM_FUNC_SUBTRACT: return "Substract"; - case CELL_GCM_FUNC_REVERSE_SUBTRACT: return "Reverse_substract"; - case CELL_GCM_MIN: return "Min"; - case CELL_GCM_MAX: return "Max"; - case CELL_GCM_FUNC_ADD_SIGNED: return "Add_signed"; - case CELL_GCM_FUNC_REVERSE_ADD_SIGNED: return "Reverse_add_signed"; - case CELL_GCM_FUNC_REVERSE_SUBTRACT_SIGNED: return "Reverse_substract_signed"; - } - return "Error"; - } - - std::string get_logic_op(u32 op) - { - switch (op) - { - case CELL_GCM_CLEAR: return "Clear"; - case CELL_GCM_AND: return "And"; - case CELL_GCM_AND_REVERSE: return "And_reverse"; - case CELL_GCM_COPY: return "Copy"; - case CELL_GCM_AND_INVERTED: return "And_inverted"; - case CELL_GCM_NOOP: return "Noop"; - case CELL_GCM_XOR: return "Xor"; - case CELL_GCM_OR: return "Or"; - case CELL_GCM_NOR: return "Nor"; - case CELL_GCM_EQUIV: return "Equiv"; - case CELL_GCM_INVERT: return "Invert"; - case CELL_GCM_OR_REVERSE: return "Or_reverse"; - case CELL_GCM_COPY_INVERTED: return "Copy_inverted"; - case CELL_GCM_OR_INVERTED: return "Or_inverted"; - case CELL_GCM_NAND: return "Nand"; - } - return "Error"; - } - - std::string get_compare_func(u32 op) - { - switch (op) - { - case CELL_GCM_NEVER: return "Never"; - case CELL_GCM_LESS: return "Less"; - case CELL_GCM_EQUAL: return "Equal"; - case CELL_GCM_LEQUAL: return "Less_equal"; - case CELL_GCM_GREATER: return "Greater"; - case CELL_GCM_NOTEQUAL: return "Not_equal"; - case CELL_GCM_GEQUAL: return "Greater_equal"; - case CELL_GCM_ALWAYS: return "Always"; - } - return "Error"; - } - - std::string get_primitive_mode(u8 draw_mode) - { - switch (rsx::to_primitive_type(draw_mode)) - { - case rsx::primitive_type::points: return "Points"; - case rsx::primitive_type::lines: return "Lines"; - case rsx::primitive_type::line_loop: return "Line_loop"; - case rsx::primitive_type::line_strip: return "Line_strip"; - case rsx::primitive_type::triangles: return "Triangles"; - case rsx::primitive_type::triangle_strip: return "Triangle_strip"; - case rsx::primitive_type::triangle_fan: return "Triangle_fan"; - case rsx::primitive_type::quads: return "Quads"; - case rsx::primitive_type::quad_strip: return "Quad_strip"; - case rsx::primitive_type::polygon: return "Polygon"; - } - return "Error"; - } - std::string ptr_to_string(u32 ptr) { return fmt::format("0x%08x", ptr); @@ -1407,54 +1775,9 @@ namespace return "Error"; } - - std::string depth_stencil_surface_format(u32 format) - { - switch (rsx::to_surface_depth_format(format)) - { - case rsx::surface_depth_format::z16: return "CELL_GCM_SURFACE_Z16"; - case rsx::surface_depth_format::z24s8: return "CELL_GCM_SURFACE_Z24S8"; - } - return "Error"; - } - - std::string surface_antialiasing(u8 format) - { - switch (rsx::to_surface_antialiasing(format)) - { - case rsx::surface_antialiasing::center_1_sample: return "1 sample centered"; - case rsx::surface_antialiasing::diagonal_centered_2_samples: return "2 samples diagonal centered"; - case rsx::surface_antialiasing::square_centered_4_samples: return "4 samples square centered"; - case rsx::surface_antialiasing::square_rotated_4_samples: return "4 samples diagonal rotated"; - } - return "Error"; - } - - std::string surface_color_format(u32 format) - { - switch (rsx::to_surface_color_format(format)) - { - case rsx::surface_color_format::x1r5g5b5_z1r5g5b5: return "CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5"; - case rsx::surface_color_format::x1r5g5b5_o1r5g5b5: return "CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5"; - case rsx::surface_color_format::r5g6b5 : return "CELL_GCM_SURFACE_R5G6B5"; - case rsx::surface_color_format::x8r8g8b8_z8r8g8b8: return "CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8"; - case rsx::surface_color_format::x8r8g8b8_o8r8g8b8: return "CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8"; - case rsx::surface_color_format::a8r8g8b8: return "CELL_GCM_SURFACE_A8R8G8B8"; - case rsx::surface_color_format::b8: return "CELL_GCM_SURFACE_B8"; - case rsx::surface_color_format::g8b8: return "CELL_GCM_SURFACE_G8B8"; - case rsx::surface_color_format::w16z16y16x16: return "CELL_GCM_SURFACE_F_W16Z16Y16X16"; - case rsx::surface_color_format::w32z32y32x32: return "CELL_GCM_SURFACE_F_W32Z32Y32X32"; - case rsx::surface_color_format::x32: return "CELL_GCM_SURFACE_F_X32"; - case rsx::surface_color_format::x8b8g8r8_z8b8g8r8: return "CELL_GCM_SURFACE_X8B8G8R8_Z8B8G8R8"; - case rsx::surface_color_format::x8b8g8r8_o8b8g8r8: return "CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8"; - case rsx::surface_color_format::a8b8g8r8: return "CELL_GCM_SURFACE_A8B8G8R8"; - } - return "Error"; - } - std::string texture_dimension(u8 dim) { - switch(rsx::to_texture_dimension(dim)) + switch (rsx::to_texture_dimension(dim)) { case rsx::texture_dimension::dimension1d: return "1D"; case rsx::texture_dimension::dimension2d: return "2D"; @@ -1463,51 +1786,6 @@ namespace return ""; } - std::string surface_target(u32 target) - { - switch (rsx::to_surface_target(target)) - { - case rsx::surface_target::none: return "none"; - case rsx::surface_target::surface_a: return "surface A"; - case rsx::surface_target::surface_b: return "surface B"; - case rsx::surface_target::surfaces_a_b: return "surfaces A and B"; - case rsx::surface_target::surfaces_a_b_c: return "surfaces A, B and C"; - case rsx::surface_target::surfaces_a_b_c_d: return "surfaces A,B, C and D"; - } - return "Error"; - } - - std::string get_clear_color(u32 clear_color) - { - u8 clear_a = clear_color >> 24; - u8 clear_r = clear_color >> 16; - u8 clear_g = clear_color >> 8; - u8 clear_b = clear_color; - return "A = " + std::to_string(clear_a / 255.0f) + " R = " + std::to_string(clear_r / 255.0f) + " G = " + std::to_string(clear_g / 255.0f) + " B = " + std::to_string(clear_b / 255.0f); - } - - static std::string get_zstencil_clear(u32 zstencil) - { - u32 depth = zstencil >> 8; - u32 stencil = zstencil & 0xff; - return "Z = " + std::to_string(depth) + " S = " + std::to_string(stencil); - } - - std::string get_stencil_op(u32 op) - { - switch (op) - { - case CELL_GCM_KEEP: return "Keep"; - case CELL_GCM_ZERO: return "Zero"; - case CELL_GCM_REPLACE: return "Replace"; - case CELL_GCM_INCR: return "Incr"; - case CELL_GCM_DECR: return "Decr"; - case CELL_GCM_INCR_WRAP: return "Incr_wrap"; - case CELL_GCM_DECR_WRAP: return "Decr_wrap"; - } - return "Error"; - } - std::string get_vertex_attribute_format(u8 type) { switch (rsx::to_vertex_base_type(type)) @@ -1534,16 +1812,6 @@ namespace return "Type = " + get_vertex_attribute_format(type) + " size = " + std::to_string(size) + " stride = " + std::to_string(stride) + " frequency = " + std::to_string(frequency); } - std::string index_type(u16 arg) - { - switch (rsx::to_index_array_type(arg)) - { - case rsx::index_array_type::u16: return "unsigned short"; - case rsx::index_array_type::u32: return "unsigned int"; - } - return "Error"; - } - std::string transform_constant(size_t index, u32 arg) { return "Transform constant " + std::to_string(index) + ": " + std::to_string(arg) + "/" + std::to_string((float&)arg); @@ -1655,7 +1923,7 @@ namespace { switch (rsx::to_texture_max_anisotropy(aniso)) { - case rsx::texture_max_anisotropy::x1 : return "1"; + case rsx::texture_max_anisotropy::x1: return "1"; case rsx::texture_max_anisotropy::x2: return "2"; case rsx::texture_max_anisotropy::x4: return "4"; case rsx::texture_max_anisotropy::x6: return "6"; @@ -1729,256 +1997,23 @@ namespace " b_signed = " + std::to_string((arg >> 31) & 0x1); } - std::string vertex_input_mask(u32 arg) + namespace { - const std::string input_names[] = + template + auto create_printing_table(const std::integer_sequence &) { - "in_pos", "in_weight", "in_normal", - "in_diff_color", "in_spec_color", - "in_fog", - "in_point_size", "in_7", - "in_tc0", "in_tc1", "in_tc2", "in_tc3", - "in_tc4", "in_tc5", "in_tc6", "in_tc7" - }; - std::string result = "Transform program enabled inputs:"; - for (unsigned i = 0; i < 16; i++) - if (arg & (1 << i)) - result += input_names[i] + " "; - return result; - } - - std::string vertex_output_mask(u32 arg) - { - const std::string output_names[] = - { - "diffuse_color", - "specular_color", - "back_diffuse_color", - "back_specular_color", - "fog", - "point_size", - "clip_distance[0]", - "clip_distance[1]", - "clip_distance[2]", - "clip_distance[3]", - "clip_distance[4]", - "clip_distance[5]", - "tc8", - "tc9", - "tc0", - "tc1", - "tc2", - "tc3", - "tc4", - "tc5", - "tc6", - "tc7" - }; - std::string result = "Transform program outputs:"; - for (unsigned i = 0; i < 22; i++) - if (arg & (1 << i)) - result += output_names[i] + " "; - return result; - } - - std::string shader_control(u32 arg) - { - return "Shader control: raw_value =" + std::to_string(arg) + - " reg_count = " + std::to_string((arg >> 24) & 0xFF) + - ((arg & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT) ? " depth_replace " : "") + - ((arg & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS) ? " 32b_exports " : ""); - } - - std::string anti_aliasing_control(u32 arg) - { - std::string result = "Anti_aliasing: "; - if (arg & 0x1) - result += "enabled"; - else - result += "disabled"; - result += " alpha_to_coverage = "; - if ((arg >> 4) & 0x1) - result += "enabled"; - else - result += "disabled"; - result += " alpha_to_one = "; - if ((arg >> 8) & 0x1) - result += "enabled"; - else - result += "disabled"; - result += " sample_mask = " + ptr_to_string(arg >> 16); - return result; - } - - std::string origin_mode(u32 origin) - { - switch (rsx::to_window_origin(origin)) - { - case rsx::window_origin::bottom: return "bottom"; - case rsx::window_origin::top: return "top"; + return std::unordered_map{ {opcode, rsx::print_register_value}... }; } - throw EXCEPTION("Wrong origin mode"); } - std::string pixel_center_mode(u32 in) - { - switch (rsx::to_window_pixel_center(in)) - { - case rsx::window_pixel_center::half: return "half"; - case rsx::window_pixel_center::integer: return "integer"; - } - throw EXCEPTION("Wrong origin mode"); - } - - std::string shader_window(u32 arg) - { - return "Viewport: height = " + std::to_string(arg & 0xFFF) + " origin = " + origin_mode((arg >> 12) & 0xF) + " pixel center = " + pixel_center_mode((arg >> 16) & 0xF); - } - -#define OPCODE_RANGE_1(opcode, increment, index, printing_function) \ - { (opcode) + (index) * (increment), [](u32 arg) -> std::string { return (printing_function)((index), arg); } }, - -#define OPCODE_RANGE_2(opcode, increment, index, printing_function) \ - OPCODE_RANGE_1((opcode), (increment), (index), (printing_function)) \ - OPCODE_RANGE_1((opcode), (increment), (index) + 1, (printing_function)) - -#define OPCODE_RANGE_4(opcode, increment, index, printing_function) \ - OPCODE_RANGE_2((opcode), (increment), (index), (printing_function)) \ - OPCODE_RANGE_2((opcode), (increment), (index) + 2, (printing_function)) - -#define OPCODE_RANGE_8(opcode, increment, index, printing_function) \ - OPCODE_RANGE_4((opcode), (increment), (index), (printing_function)) \ - OPCODE_RANGE_4((opcode), (increment), (index) + 4, (printing_function)) - -#define OPCODE_RANGE_16(opcode, increment, index, printing_function) \ - OPCODE_RANGE_8((opcode), (increment), (index), (printing_function)) \ - OPCODE_RANGE_8((opcode), (increment), (index) + 8, (printing_function)) - -#define OPCODE_RANGE_32(opcode, increment, index, printing_function) \ - OPCODE_RANGE_16((opcode), (increment), (index), (printing_function)) \ - OPCODE_RANGE_16((opcode), (increment), (index) + 16, (printing_function)) - -#define OPCODE_RANGE_64(opcode, increment, index, printing_function) \ - OPCODE_RANGE_32((opcode), (increment), (index), (printing_function)) \ - OPCODE_RANGE_32((opcode), (increment), (index) + 32, (printing_function)) - - const std::unordered_map printing_functions = - { - { NV4097_NO_OPERATION , [](u32) -> std::string { return "(nop)"; } }, - { NV4097_SET_ALPHA_TEST_ENABLE, [](u32 arg) -> std::string { return (!!arg) ? "Alpha: enable" : "Alpha: disable"; } }, - { NV4097_SET_DEPTH_TEST_ENABLE, [](u32 arg) -> std::string { return (!!arg) ? "Depth: enable" : "Depth: disable"; } }, - { NV4097_SET_DEPTH_MASK, [](u32 arg) -> std::string { return (!!arg) ? "Depth: write enabled" : "Depth: write disabled"; } }, - { NV4097_SET_DEPTH_FUNC, [](u32 arg) -> std::string { return "Depth: " + get_compare_func(arg); } }, - { NV4097_SET_LOGIC_OP_ENABLE, [](u32 arg) -> std::string { return (!!arg) ? "Logic Op: enable" : "Logic Op: disable"; } }, - { NV4097_SET_LOGIC_OP, [](u32 arg) -> std::string { return "Logic Op: " + get_logic_op(arg); } }, - { NV4097_SET_BLEND_ENABLE, [](u32 arg) -> std::string { return (!!arg) ? "Blend: enable" : "Blend: disable"; } }, - { NV4097_SET_BLEND_FUNC_SFACTOR, [](u32 arg) -> std::string { return "Blend: sfactor.rgb = " + get_blend_factor(arg & 0xFFFF) + " sfactor.a = " + get_blend_factor(arg >> 16); } }, - { NV4097_SET_BLEND_FUNC_DFACTOR, [](u32 arg) -> std::string { return "Blend: dfactor.rgb = " + get_blend_factor(arg & 0xFFFF) + " dfactor.a = " + get_blend_factor(arg >> 16); } }, - { NV4097_SET_BLEND_EQUATION , [](u32 arg) -> std::string { return "Blend: op.rgb = " + get_blend_op(arg & 0xFFFF) + " op.a = " + get_blend_op(arg >> 16); } }, - { NV4097_SET_BLEND_ENABLE_MRT, [](u32 arg) -> std::string { return "Blend: mrt0 = " + std::to_string(!!(arg & 0x2)) + " mrt1 = " + std::to_string(!!(arg & 0x4)) + " mrt2 = " + std::to_string(!!(arg & 0x8)); } }, - { NV4097_SET_COLOR_MASK , [](u32 arg) -> std::string { return "Color mask: A = " + std::to_string(!!(arg & 0x1000000)) + " R = " + std::to_string(!!(arg & 0x10000)) + " G = " + std::to_string(!!(arg & 0x100)) + " B = " + std::to_string(!!(arg & 0x1)); } }, - { NV4097_SET_VIEWPORT_HORIZONTAL, [](u32 arg) -> std::string { return "Viewport: x = " + std::to_string(arg & 0xFFFF) + " width = " + std::to_string(arg >> 16); } }, - { NV4097_SET_VIEWPORT_VERTICAL, [](u32 arg) -> std::string { return "Viewport: y = " + std::to_string(arg & 0xFFFF) + " height = " + std::to_string(arg >> 16); } }, - { NV4097_SET_BEGIN_END, [](u32 arg) -> std::string { return arg ? "- Begin: " + get_primitive_mode(arg) + " -" : "- End -"; } }, + const std::unordered_map printing_functions = create_printing_table(rsx::opcode_list); +/* { { NV4097_DRAW_ARRAYS, [](u32 arg) -> std::string { return "Draw " + std::to_string((arg >> 24) + 1) + " vertex starting from " + std::to_string(arg & 0xFFFFFF); } }, { NV4097_DRAW_INDEX_ARRAY, [](u32 arg) -> std::string { return "Draw " + std::to_string((arg >> 24) + 1) + " index starting from " + std::to_string(arg & 0xFFFFFF); } }, { NV4097_SET_SEMAPHORE_OFFSET, [](u32 arg) -> std::string { return "Semaphore: @ " + ptr_to_string(arg); } }, { NV4097_TEXTURE_READ_SEMAPHORE_RELEASE, [](u32 arg) -> std::string { return "Write semaphore value " + std::to_string(arg); } }, { NV4097_CLEAR_SURFACE, [](u32 arg) -> std::string { return "Clear surface " + std::string(arg & 0x1 ? "Depth " : "") + std::string(arg & 0x2 ? "Stencil " : "") + std::string(arg & 0xF0 ? "Color " : ""); } }, - { NV4097_SET_CONTEXT_DMA_COLOR_A, [](u32 arg) -> std::string { return "Surface A: DMA mode = " + dma_mode(arg);} }, - { NV4097_SET_SURFACE_PITCH_A, [](u32 arg) -> std::string { return "Surface A: Pitch = " + std::to_string(arg); } }, - { NV4097_SET_SURFACE_COLOR_AOFFSET, [](u32 arg) -> std::string { return "Surface A: Offset = " + ptr_to_string(arg); } }, - { NV4097_SET_CONTEXT_DMA_COLOR_B, [](u32 arg) -> std::string { return "Surface B: DMA mode = " + dma_mode(arg);} }, - { NV4097_SET_SURFACE_PITCH_B, [](u32 arg) -> std::string { return "Surface B: Pitch = " + std::to_string(arg); } }, - { NV4097_SET_SURFACE_COLOR_BOFFSET, [](u32 arg) -> std::string { return "Surface B: Offset = " + ptr_to_string(arg); } }, - { NV4097_SET_CONTEXT_DMA_COLOR_C, [](u32 arg) -> std::string { return "Surface C: DMA mode = " + dma_mode(arg);} }, - { NV4097_SET_SURFACE_PITCH_C, [](u32 arg) -> std::string { return "Surface C: Pitch = " + std::to_string(arg); } }, - { NV4097_SET_SURFACE_COLOR_COFFSET, [](u32 arg) -> std::string { return "Surface C: Offset = " + ptr_to_string(arg); } }, - { NV4097_SET_SURFACE_PITCH_D, [](u32 arg) -> std::string { return "Surface D: Pitch = " + std::to_string(arg); } }, - { NV4097_SET_SURFACE_COLOR_DOFFSET, [](u32 arg) -> std::string { return "Surface D: Offset = " + ptr_to_string(arg); } }, - { NV4097_SET_CONTEXT_DMA_COLOR_D, [](u32 arg) -> std::string { return "Surface D: DMA mode = " + dma_mode(arg);} }, - { NV4097_SET_SURFACE_PITCH_Z, [](u32 arg) -> std::string { return "Surface Zeta: Pitch = " + std::to_string(arg); } }, - { NV4097_SET_SURFACE_ZETA_OFFSET, [](u32 arg) -> std::string { return "Surface Zeta: Offset = " + ptr_to_string(arg); } }, - { NV4097_SET_CONTEXT_DMA_ZETA, [](u32 arg) -> std::string { return "Surface Zeta: DMA mode = " + dma_mode(arg);} }, - { NV4097_SET_SURFACE_FORMAT, [](u32 arg) -> std::string { return "Surface: Color format = " + surface_color_format(arg & 0x1F) + " DepthStencil format = " + depth_stencil_surface_format((arg >> 5) & 0x7) + " Anti aliasing =" + surface_antialiasing((arg >> 12) & 0x7); } }, - { NV4097_SET_SURFACE_CLIP_HORIZONTAL, [](u32 arg) -> std::string { return "Surface: clip x = " + std::to_string(arg & 0xFFFF) + " width = " + std::to_string(arg >> 16); } }, - { NV4097_SET_SURFACE_CLIP_VERTICAL, [](u32 arg) -> std::string { return "Surface: clip y = " + std::to_string(arg & 0xFFFF) + " height = " + std::to_string(arg >> 16); } }, - { NV4097_SET_SURFACE_COLOR_TARGET, [](u32 arg) -> std::string { return "Surface: Targets " + surface_target(arg); } }, - { NV4097_SET_COLOR_CLEAR_VALUE, [](u32 arg) -> std::string { return "Clear: " + get_clear_color(arg); } }, - { NV4097_SET_ZSTENCIL_CLEAR_VALUE, [](u32 arg) -> std::string { return "Clear: " + get_zstencil_clear(arg); } }, - { NV4097_SET_CLIP_MIN, [](u32 arg) -> std::string { return "Depth: Min = " + std::to_string((f32&)arg); } }, - { NV4097_SET_CLIP_MAX, [](u32 arg) -> std::string { return "Depth: Max = " + std::to_string((f32&)arg); } }, - { NV4097_SET_VIEWPORT_SCALE, [](u32 arg) -> std::string { return "Viewport: x scale = " + std::to_string((f32&)arg); } }, - { NV4097_SET_VIEWPORT_SCALE + 1, [](u32 arg) -> std::string { return "Viewport: y scale = " + std::to_string((f32&)arg); } }, - { NV4097_SET_VIEWPORT_SCALE + 2, [](u32 arg) -> std::string { return "Viewport: z scale = " + std::to_string((f32&)arg); } }, - { NV4097_SET_VIEWPORT_OFFSET, [](u32 arg) -> std::string { return "Viewport: x offset = " + std::to_string((f32&)arg); } }, - { NV4097_SET_VIEWPORT_OFFSET + 1, [](u32 arg) -> std::string { return "Viewport: y offset = " + std::to_string((f32&)arg); } }, - { NV4097_SET_VIEWPORT_OFFSET + 2, [](u32 arg) -> std::string { return "Viewport: z offset = " + std::to_string((f32&)arg); } }, - { NV4097_SET_SCISSOR_HORIZONTAL, [](u32 arg) -> std::string { return "Scissor: x = " + std::to_string(arg & 0xFFFF) + " width = " + std::to_string(arg >> 16); } }, - { NV4097_SET_SCISSOR_VERTICAL, [](u32 arg) -> std::string { return "Scissor: y = " + std::to_string(arg & 0xFFFF) + " height = " + std::to_string(arg >> 16); } }, - { NV4097_SET_STENCIL_TEST_ENABLE, [](u32 arg) -> std::string { return (!!arg) ? "Stencil: Enable" : "Stencil : Disable"; } }, - { NV4097_SET_STENCIL_FUNC, [](u32 arg) -> std::string { return "Stencil: " + get_compare_func(arg); } }, - { NV4097_SET_BACK_STENCIL_OP_ZPASS, [](u32 arg) -> std::string { return "Stencil: Back ZPass = " + get_stencil_op(arg); } }, - { NV4097_SET_BACK_STENCIL_OP_ZFAIL, [](u32 arg) -> std::string { return "Stencil: Back ZFail = " + get_stencil_op(arg); } }, - { NV4097_SET_BACK_STENCIL_OP_FAIL, [](u32 arg) -> std::string { return "Stencil: Back Fail = " + get_stencil_op(arg); } }, - { NV4097_SET_STENCIL_OP_ZPASS, [](u32 arg) -> std::string { return "Stencil: ZPass = " + get_stencil_op(arg); } }, - { NV4097_SET_STENCIL_OP_ZFAIL, [](u32 arg) -> std::string { return "Stencil: ZFail = " + get_stencil_op(arg); } }, - { NV4097_SET_STENCIL_OP_FAIL, [](u32 arg) -> std::string { return "Stencil: Fail = " + get_stencil_op(arg); } }, - { NV4097_SET_STENCIL_FUNC_MASK, [](u32 arg) -> std::string { return "Stencil: Func mask = " + ptr_to_string(arg); } }, - { NV4097_SET_STENCIL_MASK, [](u32 arg) -> std::string { return "Stencil: Mask = " + ptr_to_string(arg); } }, - { NV4097_SET_STENCIL_FUNC_REF, [](u32 arg) -> std::string { return "Stencil: Ref = " + std::to_string(arg); } }, - { NV4097_INVALIDATE_VERTEX_CACHE_FILE, [](u32) -> std::string { return "(invalidate vertex cache file)"; } }, - { NV4097_INVALIDATE_VERTEX_FILE, [](u32) -> std::string { return "(invalidate vertex file)"; } }, - { NV4097_SET_VERTEX_ATTRIB_INPUT_MASK, vertex_input_mask}, - { NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK, vertex_output_mask }, - { NV4097_SET_SHADER_CONTROL, shader_control }, - { NV4097_SET_ANTI_ALIASING_CONTROL, anti_aliasing_control }, - { NV4097_SET_SHADER_WINDOW, shader_window }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT, [](u32 arg) -> std::string { return "Vertex array 0: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 1, [](u32 arg) -> std::string { return "Vertex array 1: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 2, [](u32 arg) -> std::string { return "Vertex array 2: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 3, [](u32 arg) -> std::string { return "Vertex array 3: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 4, [](u32 arg) -> std::string { return "Vertex array 4: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 5, [](u32 arg) -> std::string { return "Vertex array 5: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 6, [](u32 arg) -> std::string { return "Vertex array 6: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 7, [](u32 arg) -> std::string { return "Vertex array 7: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 8, [](u32 arg) -> std::string { return "Vertex array 8: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 9, [](u32 arg) -> std::string { return "Vertex array 9: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 10, [](u32 arg) -> std::string { return "Vertex array 10: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 11, [](u32 arg) -> std::string { return "Vertex array 11: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 12, [](u32 arg) -> std::string { return "Vertex array 12: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 13, [](u32 arg) -> std::string { return "Vertex array 13: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 14, [](u32 arg) -> std::string { return "Vertex array 14: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_FORMAT + 15, [](u32 arg) -> std::string { return "Vertex array 15: " + unpack_vertex_format(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET, [](u32 arg) -> std::string { return "Vertex array 0: Offset = " + std::to_string(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 1, [](u32 arg) -> std::string { return "Vertex array 1: Offset = " + std::to_string(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 2, [](u32 arg) -> std::string { return "Vertex array 2: Offset = " + std::to_string(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 3, [](u32 arg) -> std::string { return "Vertex array 3: Offset = " + std::to_string(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 4, [](u32 arg) -> std::string { return "Vertex array 4: Offset = " + std::to_string(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 5, [](u32 arg) -> std::string { return "Vertex array 5: Offset = " + std::to_string(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 6, [](u32 arg) -> std::string { return "Vertex array 6: Offset = " + std::to_string(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 7, [](u32 arg) -> std::string { return "Vertex array 7: Offset = " + std::to_string(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 8, [](u32 arg) -> std::string { return "Vertex array 8: Offset = " + std::to_string(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 9, [](u32 arg) -> std::string { return "Vertex array 9: Offset = " + std::to_string(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 10, [](u32 arg) -> std::string { return "Vertex array 10: Offset = " + std::to_string(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 11, [](u32 arg) -> std::string { return "Vertex array 11: Offset = " + std::to_string(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 12, [](u32 arg) -> std::string { return "Vertex array 12: Offset = " + std::to_string(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 13, [](u32 arg) -> std::string { return "Vertex array 13: Offset = " + std::to_string(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 14, [](u32 arg) -> std::string { return "Vertex array 14: Offset = " + std::to_string(arg); } }, - { NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + 15, [](u32 arg) -> std::string { return "Vertex array 15: Offset = " + std::to_string(arg); } }, - { NV4097_SET_INDEX_ARRAY_ADDRESS, [](u32 arg) -> std::string { return "Index array: Address = " + ptr_to_string(arg); } }, - { NV4097_SET_INDEX_ARRAY_DMA, [](u32 arg) -> std::string { return "Index array: DMA mode = " + dma_mode(arg & 0xF) + " type = " + index_type(arg >> 4); } }, - OPCODE_RANGE_32(NV4097_SET_TRANSFORM_CONSTANT, 1, 0, transform_constant) - OPCODE_RANGE_16(NV4097_SET_TEXTURE_OFFSET, 8, 0, texture_offset) - OPCODE_RANGE_16(NV4097_SET_TEXTURE_FORMAT, 8, 0, texture_format) - OPCODE_RANGE_16(NV4097_SET_TEXTURE_IMAGE_RECT, 8, 0, texture_size) - OPCODE_RANGE_16(NV4097_SET_TEXTURE_ADDRESS, 8, 0, texture_address) - OPCODE_RANGE_16(NV4097_SET_TEXTURE_CONTROL0, 8, 0, texture_control0) - OPCODE_RANGE_16(NV4097_SET_TEXTURE_CONTROL1, 8, 0, texture_control1) - OPCODE_RANGE_16(NV4097_SET_TEXTURE_CONTROL3, 1, 0, texture_control3) - OPCODE_RANGE_16(NV4097_SET_TEXTURE_BORDER_COLOR, 8, 0, texture_border_color) - OPCODE_RANGE_16(NV4097_SET_TEXTURE_FILTER, 8, 0, texture_filter) - }; + };*/ } std::function rsx::get_pretty_printing_function(u32 id) diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index 37e79f26ac..bf4d35c298 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -48,6 +48,7 @@ namespace rsx enum class primitive_type : u8 { + invalid, points, lines, line_loop, // line strip with last end being joined with first end. @@ -310,6 +311,23 @@ namespace rsx user_clip_plane_op to_user_clip_plane_op(u8 in); + enum class shading_mode : u8 + { + smooth, + flat, + }; + + shading_mode to_shading_mode(u32 in); + + enum class polygon_mode : u8 + { + point, + line, + fill, + }; + + polygon_mode to_polygon_mode(u32 in); + namespace blit_engine { enum class transfer_origin : u8 @@ -410,12 +428,6 @@ enum CellRescTableElement CELL_RESC_ELEMENT_FLOAT = 1, }; -enum -{ - CELL_GCM_FLAT = 0x1D00, - CELL_GCM_SMOOTH = 0x1D01, -}; - enum { CELL_GCM_SYSTEM_MODE_IOMAP_512MB = 1, @@ -563,28 +575,6 @@ enum CELL_GCM_ZERO = 0, CELL_GCM_ONE = 1, - CELL_GCM_SRC_COLOR = 0x0300, - CELL_GCM_ONE_MINUS_SRC_COLOR = 0x0301, - CELL_GCM_SRC_ALPHA = 0x0302, - CELL_GCM_ONE_MINUS_SRC_ALPHA = 0x0303, - CELL_GCM_DST_ALPHA = 0x0304, - CELL_GCM_ONE_MINUS_DST_ALPHA = 0x0305, - CELL_GCM_DST_COLOR = 0x0306, - CELL_GCM_ONE_MINUS_DST_COLOR = 0x0307, - CELL_GCM_SRC_ALPHA_SATURATE = 0x0308, - CELL_GCM_CONSTANT_COLOR = 0x8001, - CELL_GCM_ONE_MINUS_CONSTANT_COLOR = 0x8002, - CELL_GCM_CONSTANT_ALPHA = 0x8003, - CELL_GCM_ONE_MINUS_CONSTANT_ALPHA = 0x8004, - - CELL_GCM_FUNC_ADD = 0x8006, - CELL_GCM_MIN = 0x8007, - CELL_GCM_MAX = 0x8008, - CELL_GCM_FUNC_SUBTRACT = 0x800A, - CELL_GCM_FUNC_REVERSE_SUBTRACT = 0x800B, - CELL_GCM_FUNC_REVERSE_SUBTRACT_SIGNED = 0x0000F005, - CELL_GCM_FUNC_ADD_SIGNED = 0x0000F006, - CELL_GCM_FUNC_REVERSE_ADD_SIGNED = 0x0000F007, CELL_GCM_FRONT = 0x0404, CELL_GCM_BACK = 0x0405, @@ -593,30 +583,6 @@ enum CELL_GCM_CW = 0x0900, CELL_GCM_CCW = 0x0901, - CELL_GCM_CLEAR = 0x1500, - CELL_GCM_AND = 0x1501, - CELL_GCM_AND_REVERSE = 0x1502, - CELL_GCM_COPY = 0x1503, - CELL_GCM_AND_INVERTED = 0x1504, - CELL_GCM_NOOP = 0x1505, - CELL_GCM_XOR = 0x1506, - CELL_GCM_OR = 0x1507, - CELL_GCM_NOR = 0x1508, - CELL_GCM_EQUIV = 0x1509, - CELL_GCM_INVERT = 0x150A, - CELL_GCM_OR_REVERSE = 0x150B, - CELL_GCM_COPY_INVERTED = 0x150C, - CELL_GCM_OR_INVERTED = 0x150D, - CELL_GCM_NAND = 0x150E, - CELL_GCM_SET = 0x150F, - - CELL_GCM_KEEP = 0x1E00, - CELL_GCM_REPLACE = 0x1E01, - CELL_GCM_INCR = 0x1E02, - CELL_GCM_DECR = 0x1E03, - CELL_GCM_INCR_WRAP = 0x8507, - CELL_GCM_DECR_WRAP = 0x8508, - CELL_GCM_TRANSFER_LOCAL_TO_LOCAL = 0, CELL_GCM_TRANSFER_MAIN_TO_LOCAL = 1, CELL_GCM_TRANSFER_LOCAL_TO_MAIN = 2, @@ -696,10 +662,6 @@ enum CELL_GCM_ATTRIB_OUTPUT_MASK_TEX6 = 1 << CELL_GCM_ATTRIB_OUTPUT_TEX6, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX7 = 1 << CELL_GCM_ATTRIB_OUTPUT_TEX7, - CELL_GCM_POLYGON_MODE_POINT = 0x1B00, - CELL_GCM_POLYGON_MODE_LINE = 0x1B01, - CELL_GCM_POLYGON_MODE_FILL = 0x1B02, - CELL_GCM_TRUE = 1, CELL_GCM_FALSE = 0, }; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 33c27b20dd..e5f8cbf4e6 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -468,7 +468,7 @@ namespace rsx //LOG_NOTICE(RSX, "%s(0x%x) = 0x%x", get_method_name(reg).c_str(), reg, value); - method_registers[reg] = value; + method_registers.decode(reg, value); if (capture_current_frame) { diff --git a/rpcs3/Emu/RSX/rsx_decode.h b/rpcs3/Emu/RSX/rsx_decode.h new file mode 100644 index 0000000000..a97d11974d --- /dev/null +++ b/rpcs3/Emu/RSX/rsx_decode.h @@ -0,0 +1,2472 @@ +#pragma once +#include "Utilities/types.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" : + subreg == 1 ? "y" : + subreg == 2 ? "z" : + "w"; + } +} + +namespace rsx +{ + std::string print_boolean(bool b); + std::string print_comparaison_function(comparaison_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); + +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<> +struct registers_decoder : + public as_u16x2<&rsx_state::m_viewport_origin_x, &rsx_state::m_viewport_width> +{ + static std::string dump(std::tuple &&decoded_values) + { + return "Viewport: x = " + std::to_string(std::get<0>(decoded_values)) + " width = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +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) + { + return "Viewport: y = " + std::to_string(std::get<0>(decoded_values)) + " height = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +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) + { + return "Scissor: x = " + std::to_string(std::get<0>(decoded_values)) + " width = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +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) + { + return "Scissor: y = " + std::to_string(std::get<0>(decoded_values)) + " height = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +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) + { + return "Surface: clip x = " + std::to_string(std::get<0>(decoded_values)) + " width = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +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) + { + return "Surface: clip y = " + std::to_string(std::get<0>(decoded_values)) + " height = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +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) + { + return "Clear: rect x = " + std::to_string(std::get<0>(decoded_values)) + " width = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +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) + { + return "Clear: rect y = " + std::to_string(std::get<0>(decoded_values)) + " height = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +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) + { + return "Blit engine: clip x = " + std::to_string(std::get<0>(decoded_values)) + " y = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +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) + { + return "Blit engine: clip width = " + std::to_string(std::get<0>(decoded_values)) + " height = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +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) + { + return "Blit engine: output x = " + std::to_string(std::get<0>(decoded_values)) + " y = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +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) + { + return "Window: offset x = " + std::to_string(std::get<0>(decoded_values)) + " y = " + std::to_string(std::get<1>(decoded_values)); + } +}; + + +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) + { + return "Blit engine: output width = " + std::to_string(std::get<0>(decoded_values)) + " height = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +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) + { + return "Blit engine: input width = " + std::to_string(std::get<0>(decoded_values)) + " height = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +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) + { + return "Blit engine: output alignment = " + std::to_string(std::get<0>(decoded_values)) + " pitch = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +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) + { + return "NV308A: x = " + std::to_string(std::get<0>(decoded_values)) + " y = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +template<> +struct registers_decoder : public split_reg_half_uint_decode +{ + static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + { + std::tie(state.m_vertex_attrib_input_mask, std::ignore) = decoded_values; + } + + static std::string dump(std::tuple &&decoded_values) + { + std::string result = "Transform program enabled inputs:"; + const std::string input_names[] = + { + "in_pos", "in_weight", "in_normal", + "in_diff_color", "in_spec_color", + "in_fog", + "in_point_size", "in_7", + "in_tc0", "in_tc1", "in_tc2", "in_tc3", + "in_tc4", "in_tc5", "in_tc6", "in_tc7" + }; + for (unsigned i = 0; i < 16; i++) + if (std::get<0>(decoded_values) & (1 << i)) + result += input_names[i] + " "; + return result + " ? = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +template<> +struct registers_decoder : public split_reg_half_uint_decode +{ + static void commit_rsx_state(rsx_state &state, std::tuple &&decoded_values) + { + std::tie(state.m_frequency_divider_operation_mask, std::ignore) = decoded_values; + } + + static std::string dump(std::tuple &&decoded_values) + { + std::string result = "Frequency divider: "; + for (unsigned i = 0; i < 16; i++) + if (std::get<0>(decoded_values) & (1 << i)) + result += std::to_string(i) + " "; + return result + " ? = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_depth_test_enabled = decoded_values; + } + + static std::string dump(bool &&decoded_values) + { + return "Depth: test " + print_boolean(decoded_values); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_depth_write_enabled = decoded_values; + } + + static std::string dump(bool &&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); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_stencil_test_enabled = decoded_values; + } + + static std::string dump(bool &&decoded_values) + { + return "Stencil: test " + print_boolean(decoded_values); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_restart_index_enabled = decoded_values; + } + + static std::string dump(bool &&decoded_values) + { + return "Restart Index: " + print_boolean(decoded_values); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_depth_bounds_test_enabled = decoded_values; + } + + static std::string dump(bool &&decoded_values) + { + return "Depth: bound test " + print_boolean(decoded_values); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_logic_op_enabled = decoded_values; + } + + static std::string dump(bool &&decoded_values) + { + return "Logic: " + print_boolean(decoded_values); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_dither_enabled = decoded_values; + } + + static std::string dump(bool &&decoded_values) + { + return "Dither: " + print_boolean(decoded_values); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_blend_enabled = decoded_values; + } + + static std::string dump(bool &&decoded_values) + { + return "Blend: " + print_boolean(decoded_values); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_line_smooth_enabled = decoded_values; + } + + static std::string dump(bool &&decoded_values) + { + return "Line: smooth " + print_boolean(decoded_values); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_poly_offset_point_enabled = decoded_values; + } + + static std::string dump(bool &&decoded_values) + { + return "Polygon: offset point " + print_boolean(decoded_values); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_offset_line_enabled = decoded_values; + } + + static std::string dump(bool &&decoded_values) + { + return "Polygon: offset line " + print_boolean(decoded_values); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_poly_offset_fill_enabled = decoded_values; + } + + static std::string dump(bool &&decoded_values) + { + return "Polygon: offset fill " + print_boolean(decoded_values); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_cull_face_enabled = decoded_values; + } + + static std::string dump(bool &&decoded_values) + { + return "Cull face: " + print_boolean(decoded_values); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_poly_smooth_enabled = decoded_values; + } + + static std::string dump(bool &&decoded_values) + { + return "Polygon: smooth " + print_boolean(decoded_values); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_two_sided_stencil_test_enabled = decoded_values; + } + + static std::string dump(bool &&decoded_values) + { + return "Stencil: per side " + print_boolean(decoded_values); + } +}; + +template<> +struct registers_decoder : public as_bool +{ + static void commit_rsx_state(rsx_state &state, bool &&decoded_values) + { + state.m_two_side_light_enabled = decoded_values; + } + + static std::string dump(bool &&decoded_values) + { + return "Light: per side " + print_boolean(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_depth_bounds_min> +{ + static std::string dump(f32 &&decoded_values) + { + return "Depth: bound min = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_depth_bounds_max> +{ + static std::string dump(f32 &&decoded_values) + { + return "Depth: bound max = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_fog_params_0> +{ + static std::string dump(f32 &&decoded_values) + { + return "Fog: param 0 = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_fog_params_1> +{ + static std::string dump(f32 &&decoded_values) + { + return "Fog: param 1 = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_clip_min> +{ + static std::string dump(f32 &&decoded_values) + { + return "Depth: clip min = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_clip_max> +{ + static std::string dump(f32 &&decoded_values) + { + return "Depth: clip max = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_poly_offset_scale> +{ + static std::string dump(f32 &&decoded_values) + { + return "Polygon: offset scale = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_poly_offset_bias> +{ + static std::string dump(f32 &&decoded_values) + { + return "Polygon: offset bias = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_viewport_scale_x> +{ + static std::string dump(f32 &&decoded_values) + { + return "Viewport: scale x = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_viewport_scale_y> +{ + static std::string dump(f32 &&decoded_values) + { + return "Viewport: scale y = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_viewport_scale_z> +{ + static std::string dump(f32 &&decoded_values) + { + return "Viewport: scale z = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_viewport_scale_w> +{ + static std::string dump(f32 &&decoded_values) + { + return "Viewport: scale w = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_viewport_offset_x> +{ + static std::string dump(f32 &&decoded_values) + { + return "Viewport: offset x = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_viewport_offset_y> +{ + static std::string dump(f32 &&decoded_values) + { + return "Viewport: offset y = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_viewport_offset_z> +{ + static std::string dump(f32 &&decoded_values) + { + return "Viewport: offset z = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_f32<&rsx_state::m_viewport_offset_w> +{ + static std::string dump(f32 &&decoded_values) + { + return "Viewport: offset w = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_restart_index> +{ + static std::string dump(u32 &&decoded_values) + { + return "Restart index: " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_surface_a_offset> +{ + static std::string dump(u32 &&decoded_values) + { + return "Surface: A offset " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_surface_b_offset> +{ + static std::string dump(u32 &&decoded_values) + { + return "Surface: B offset " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_surface_c_offset> +{ + static std::string dump(u32 &&decoded_values) + { + return "Surface: C offset " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_surface_d_offset> +{ + static std::string dump(u32 &&decoded_values) + { + return "Surface: D offset " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_surface_a_pitch> +{ + static std::string dump(u32 &&decoded_values) + { + return "Surface: A pitch " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_surface_b_pitch> +{ + static std::string dump(u32 &&decoded_values) + { + return "Surface: B pitch " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_surface_c_pitch> +{ + static std::string dump(u32 &&decoded_values) + { + return "Surface: C pitch " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_surface_d_pitch> +{ + static std::string dump(u32 &&decoded_values) + { + return "Surface: D pitch " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_surface_z_offset> +{ + static std::string dump(u32 &&decoded_values) + { + return "Surface: Z offset " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_surface_z_pitch> +{ + static std::string dump(u32 &&decoded_values) + { + return "Surface: Z pitch " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_vertex_attrib_output_mask> +{ + static std::string dump(u32 &&decoded_values) + { + const std::string output_names[] = + { + "diffuse_color", + "specular_color", + "back_diffuse_color", + "back_specular_color", + "fog", + "point_size", + "clip_distance[0]", + "clip_distance[1]", + "clip_distance[2]", + "clip_distance[3]", + "clip_distance[4]", + "clip_distance[5]", + "tc8", + "tc9", + "tc0", + "tc1", + "tc2", + "tc3", + "tc4", + "tc5", + "tc6", + "tc7" + }; + std::string result = "Transform program outputs:"; + for (unsigned i = 0; i < 22; i++) + if (decoded_values & (1 << i)) + result += output_names[i] + " "; + return result; + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_shader_control> +{ + static std::string dump(u32 &&decoded_values) + { + 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 " : ""); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_vertex_data_base_offset> +{ + static std::string dump(u32 &&decoded_values) + { + return "Vertex: base offset " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_index_array_address> +{ + static std::string dump(u32 &&decoded_values) + { + return "Index: array offset " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_vertex_data_base_index> +{ + static std::string dump(u32 &&decoded_values) + { + return "Vertex: base index " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_shader_program_address> +{ + static std::string dump(u32 &&decoded_values) + { + return "Shader: program offset = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_transform_program_start> +{ + static std::string dump(u32 &&decoded_values) + { + return "Transform program: start = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_semaphore_offset_406e> +{ + static std::string dump(u32 &&decoded_values) + { + return "NV406E semaphore: offset = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_semaphore_offset_4097> +{ + static std::string dump(u32 &&decoded_values) + { + return "semaphore: offset = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_blit_engine_input_offset> +{ + static std::string dump(u32 &&decoded_values) + { + return "NV3089: input offset = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_blit_engine_output_offset_nv3062> +{ + static std::string dump(u32 &&decoded_values) + { + return "NV3062: output offset = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_blit_engine_nv309E_offset> +{ + static std::string dump(u32 &&decoded_values) + { + return "NV309E: offset = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_blit_engine_ds_dx> +{ + static std::string dump(u32 &&decoded_values) + { + return "NV3089: dsdx = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_blit_engine_dt_dy> +{ + static std::string dump(u32 &&decoded_values) + { + return "NV3089: dtdy = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_nv0039_input_pitch> +{ + static std::string dump(u32 &&decoded_values) + { + return "NV0039: input pitch = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_nv0039_output_pitch> +{ + static std::string dump(u32 &&decoded_values) + { + return "NV0039: output pitch = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_nv0039_line_length> +{ + static std::string dump(u32 &&decoded_values) + { + return "NV0039: line lenght input = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_nv0039_line_count> +{ + static std::string dump(u32 &&decoded_values) + { + return "NV0039: line count = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_nv0039_output_offset> +{ + static std::string dump(u32 &&decoded_values) + { + return "NV0039: output offset = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_nv0039_input_offset> +{ + static std::string dump(u32 &&decoded_values) + { + return "NV0039: input offset = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) { return to_comparaison_function(value); } + + static void commit_rsx_state(rsx_state &state, comparaison_function &&decoded_values) + { + state.m_depth_func = decoded_values; + } + + static std::string dump(comparaison_function &&decoded_values) + { + return "Depth: compare_function = " + print_comparaison_function(decoded_values); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) { return to_comparaison_function(value); } + + static void commit_rsx_state(rsx_state &state, comparaison_function &&decoded_values) + { + state.m_stencil_func = decoded_values; + } + + static std::string dump(comparaison_function &&decoded_values) + { + return "Stencil: (front) compare_function = " + print_comparaison_function(decoded_values); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) { return to_comparaison_function(value); } + + static void commit_rsx_state(rsx_state &state, comparaison_function &&decoded_values) + { + state.m_back_stencil_func = decoded_values; + } + + static std::string dump(comparaison_function &&decoded_values) + { + return "Stencil: back compare_function = " + print_comparaison_function(decoded_values); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) { return to_comparaison_function(value); } + + static void commit_rsx_state(rsx_state &state, comparaison_function &&decoded_values) + { + state.m_alpha_func = decoded_values; + } + + static std::string dump(comparaison_function &&decoded_values) + { + return "Alpha: compare_function = " + print_comparaison_function(decoded_values); + } +}; + +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) + { + state.m_stencil_op_fail = decoded_values; + } + + static std::string dump(stencil_op &&decoded_values) + { + return "Stencil: (front) fail op = " + print_stencil_op(decoded_values); + } +}; + +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) + { + state.m_stencil_op_zfail = decoded_values; + } + + static std::string dump(stencil_op &&decoded_values) + { + return "Stencil: (front) zfail op = " + print_stencil_op(decoded_values); + } +}; + +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) + { + state.m_stencil_op_zpass = decoded_values; + } + + static std::string dump(stencil_op &&decoded_values) + { + return "Stencil: (front) zpass op = " + print_stencil_op(decoded_values); + } +}; + +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) + { + state.m_back_stencil_op_fail = decoded_values; + } + + static std::string dump(stencil_op &&decoded_values) + { + return "Stencil: (back) fail op = " + print_stencil_op(decoded_values); + } +}; + +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) + { + state.m_back_stencil_op_zfail = decoded_values; + } + + static std::string dump(stencil_op &&decoded_values) + { + return "Stencil: (back) zfail op = " + print_stencil_op(decoded_values); + } +}; + +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) + { + state.m_back_stencil_op_zpass = decoded_values; + } + + static std::string dump(stencil_op &&decoded_values) + { + return "Stencil: (back) zpass op = " + print_stencil_op(decoded_values); + } +}; + +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) + { + state.m_stencil_func_ref = std::get<0>(decoded_values); + } + + static std::string dump(std::tuple &&decoded_values) + { + return "Stencil: (front) func ref = " + std::to_string(std::get<0>(decoded_values)); + } +}; + +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) + { + state.m_back_stencil_func_ref = std::get<0>(decoded_values); + } + + static std::string dump(std::tuple &&decoded_values) + { + return "Stencil: (back) func ref = " + std::to_string(std::get<0>(decoded_values)); + } +}; + +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) + { + state.m_stencil_func_mask = std::get<0>(decoded_values); + } + + static std::string dump(std::tuple &&decoded_values) + { + return "Stencil: (front) func mask = " + std::to_string(std::get<0>(decoded_values)); + } +}; + +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) + { + state.m_back_stencil_func_mask = std::get<0>(decoded_values); + } + + static std::string dump(std::tuple &&decoded_values) + { + return "Stencil: (back) func mask = " + std::to_string(std::get<0>(decoded_values)); + } +}; + +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) + { + state.m_alpha_ref = std::get<0>(decoded_values); + } + + static std::string dump(std::tuple &&decoded_values) + { + return "Alpha: ref = " + std::to_string(std::get<0>(decoded_values)); + } +}; + +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) + { + std::tie(state.m_clear_color_b, state.m_clear_color_g, state.m_clear_color_r, state.m_clear_color_a) = decoded_values; + } + + static std::string dump(std::tuple &&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)); + } +}; + +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) + { + state.m_stencil_mask = std::get<0>(decoded_values); + } + + static std::string dump(std::tuple &&decoded_values) + { + return "Stencil: (front) mask = " + std::to_string(std::get<0>(decoded_values)); + } +}; + +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) + { + state.m_back_stencil_mask = std::get<0>(decoded_values); + } + + static std::string dump(std::tuple &&decoded_values) + { + return "Stencil: (back) mask = " + std::to_string(std::get<0>(decoded_values)); + } +}; + +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) + { + state.m_logic_operation = decoded_values; + } + + static std::string dump(logic_op &&decoded_values) + { + return "Logic: op = " + print_logic_op(decoded_values); + } +}; + +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) + { + state.m_front_face_mode = decoded_values; + } + + static std::string dump(front_face &&decoded_values) + { + return "Front Face: " + print_front_face(decoded_values); + } +}; + + +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) + { + state.m_cull_face_mode = decoded_values; + } + + static std::string dump(cull_face &&decoded_values) + { + return "Cull Face: " + print_cull_face(decoded_values); + } +}; + +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) + { + state.m_surface_color_target = decoded_values; + } + + static std::string dump(surface_target &&decoded_values) + { + return "Surface: Color target(s) = " + print_surface_target(decoded_values); + } +}; + +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) + { + state.m_fog_equation = decoded_values; + } + + static std::string dump(fog_mode &&decoded_values) + { + return "Fog: " + print_fog_mode(decoded_values); + } +}; + +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) + { + state.m_primitive_type = decoded_values; + } + + static std::string dump(primitive_type &&decoded_values) + { + return "-- " + print_primitive_mode(decoded_values) + " --"; + } +}; + +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) + { + state.m_blit_engine_operation = decoded_values; + } + + static std::string dump(blit_engine::transfer_operation &&decoded_values) + { + return "NV3089: op = " + print_transfer_operation(decoded_values); + } +}; + +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) + { + state.m_blit_engine_src_color_format = decoded_values; + } + + static std::string dump(blit_engine::transfer_source_format &&decoded_values) + { + return "NV3089: source fmt = " + print_transfer_source_format(decoded_values); + } +}; + +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) + { + state.m_blit_engine_context_surface = decoded_values; + } + + static std::string dump(blit_engine::context_surface &&decoded_values) + { + return "NV3089: context surface = " + print_context_surface(decoded_values); + } +}; + +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) + { + state.m_blit_engine_nv3062_color_format = decoded_values; + } + + static std::string dump(blit_engine::transfer_destination_format &&decoded_values) + { + return "NV3062: output fmt = " + print_transfer_destination_format(decoded_values); + } +}; + +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) + { + state.m_blend_equation_rgb = std::get<0>(decoded_values); + state.m_blend_equation_a = std::get<1>(decoded_values); + } + + static std::string dump(std::tuple &&decoded_values) + { + return "Blend: equation rgb = " + print_blend_op(std::get<0>(decoded_values)) + " a = " + print_blend_op(std::get<1>(decoded_values)); + } +}; + +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) + { + state.m_blend_func_sfactor_rgb = std::get<0>(decoded_values); + state.m_blend_func_sfactor_a = std::get<1>(decoded_values); + } + + static std::string dump(std::tuple &&decoded_values) + { + return "Blend: sfactor rgb = " + print_blend_factor(std::get<0>(decoded_values)) + " a = " + print_blend_factor(std::get<1>(decoded_values)); + } +}; + +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) + { + state.m_blend_func_dfactor_rgb = std::get<0>(decoded_values); + state.m_blend_func_dfactor_a = std::get<1>(decoded_values); + } + + static std::string dump(std::tuple &&decoded_values) + { + return "Blend: dfactor rgb = " + print_blend_factor(std::get<0>(decoded_values)) + " a = " + print_blend_factor(std::get<1>(decoded_values)); + } +}; + +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) + { + 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); + } + + static std::string dump(std::tuple &&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)); + } +}; + +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) + { + 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); + } + + static std::string dump(std::tuple &&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)); + } +}; + +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) + { + 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); + } + + static std::string dump(std::tuple&& 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)); + } +}; + +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) + { + 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); + } + + static std::string dump(std::tuple &&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)); + } +}; + +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) + { + state.m_line_width = decoded_values; + } + + static std::string dump(f32 &&decoded_values) + { + return "Line width: " + std::to_string(decoded_values); + } +}; + +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) + { + 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); + } + + static std::string dump(std::tuple &&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)); + } +}; + +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) + { + state.m_z_clear_value = std::get<0>(decoded_values); + state.m_stencil_clear_value = std::get<1>(decoded_values); + } + + static std::string dump(std::tuple &&decoded_values) + { + return "Clear: Z = " + std::to_string(std::get<0>(decoded_values)) + + " Stencil = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +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) + { + state.m_index_type = std::get<0>(decoded_values); + state.m_index_array_location = std::get<1>(decoded_values); + } + + static std::string dump(std::tuple &&decoded_values) + { + return "Index: type = " + print_index_type(std::get<0>(decoded_values)) + + " dma = " + std::to_string(std::get<1>(decoded_values)); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) { + return value; + } + + static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + { + state.m_surface_a_dma = decoded_values; + } + + static std::string dump(u32 &&decoded_values) + { + return "Surface: A DMA = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) { + return value; + } + + static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + { + state.m_surface_b_dma = decoded_values; + } + + static std::string dump(u32 &&decoded_values) + { + return "Surface: B DMA = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) { + return value; + } + + static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + { + state.m_surface_c_dma = decoded_values; + } + + static std::string dump(u32 &&decoded_values) + { + return "Surface: C DMA = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) { + return value; + } + + static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + { + state.m_surface_d_dma = decoded_values; + } + + static std::string dump(u32 &&decoded_values) + { + return "Surface: D DMA = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) { + return value; + } + + static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + { + state.m_surface_z_dma = decoded_values; + } + + static std::string dump(u32 &&decoded_values) + { + return "Surface: Z DMA = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) { + return value; + } + + static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + { + state.m_blit_engine_input_location = decoded_values; + } + + static std::string dump(u32 &&decoded_values) + { + return "NV3089: input DMA = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_blit_engine_output_location_nv3062> +{ + static std::string dump(u32 &&decoded_values) + { + return "NV3062: output DMA = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) { + return value; + } + + static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + { + state.m_blit_engine_nv309E_location = decoded_values; + } + + static std::string dump(u32 &&decoded_values) + { + return "NV309E: output DMA = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) { + return value; + } + + static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + { + state.m_nv0039_output_location = decoded_values; + } + + static std::string dump(u32 &&decoded_values) + { + return "NV0039: output DMA = " + std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) { + return value; + } + + static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + { + state.m_nv0039_input_location = decoded_values; + } + + static std::string dump(u32 &&decoded_values) + { + return "NV0039: input DMA = " + std::to_string(decoded_values); + } +}; + +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) + { + state.m_context_dma_report = decoded_values; + } + + static std::string dump(blit_engine::context_dma &&decoded_values) + { + return "Report: context DMA = " + print_context_dma(decoded_values); + } +}; + +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) + { + 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); + } + + static std::string dump(std::tuple &&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)); + } +}; + +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) + { + 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); + } + + static std::string dump(std::tuple &&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)); + } +}; + +template<> +struct registers_decoder +{ + 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) + { + 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)); + } +}; + +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) + { + return "Blend color: 16b BA = " + std::to_string(std::get<0>(decoded_values)) + + ", " + std::to_string(std::get<1>(decoded_values)); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_blend_color> +{ + static std::string dump(u32 &&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)); + } +}; + +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) + { + 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); + } +}; + +template<> +struct registers_decoder : public as_unused +{ + static std::string dump(u32 &&decoded_values) + { + return "(nop)"; + } +}; + +template<> +struct registers_decoder : public as_unused +{ + static std::string dump(u32 &&decoded_values) + { + return "(invalidate vertex cache file)"; + } +}; + +template<> +struct registers_decoder : public as_unused +{ + static std::string dump(u32 &&decoded_values) + { + return "(invalidate vertex file)"; + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) + { + return std::make_tuple( + !!(value & 0x1), + !!((value >> 4) & 0x1), + !!((value >> 8) & 0x1), + static_cast(value >> 16) + ); + } + + 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); + } + + static std::string dump(std::tuple &&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)); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) + { + return to_shading_mode(value); + } + + static void commit_rsx_state(rsx_state &state, rsx::shading_mode &&decoded_values) + { + state.m_shading_mode = decoded_values; + } + + static std::string dump(rsx::shading_mode &&decoded_values) + { + return "Shading mode: " + print_shading_mode(decoded_values); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) + { + return to_polygon_mode(value); + } + + static void commit_rsx_state(rsx_state &state, rsx::polygon_mode &&decoded_values) + { + state.m_front_polygon_mode = decoded_values; + } + + static std::string dump(rsx::polygon_mode &&decoded_values) + { + return "Front polygon mode: " + print_polygon_mode(decoded_values); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) + { + return to_polygon_mode(value); + } + + static void commit_rsx_state(rsx_state &state, rsx::polygon_mode &&decoded_values) + { + state.m_back_polygon_mode = decoded_values; + } + + static std::string dump(rsx::polygon_mode &&decoded_values) + { + return "back polygon mode: " + print_polygon_mode(decoded_values); + } +}; + +template<> +struct registers_decoder + : as_u32<&rsx_state::m_transform_constant_file_pointer> +{ + static std::string dump(u32 &&decoded_values) + { + return "Set transform constant pointer at " + std::to_string(decoded_values); + } +}; + +#define EXPAND_RANGE_1(index, MACRO) \ + MACRO(index) + +#define EXPAND_RANGE_2(index, MACRO) \ + EXPAND_RANGE_1((index), MACRO) \ + EXPAND_RANGE_1((index) + 1, MACRO) + +#define EXPAND_RANGE_4(index, MACRO) \ + EXPAND_RANGE_2((index), MACRO) \ + EXPAND_RANGE_2((index) + 2, MACRO) + +#define EXPAND_RANGE_8(index, MACRO) \ + EXPAND_RANGE_4((index), MACRO) \ + EXPAND_RANGE_4((index) + 4, MACRO) + +#define EXPAND_RANGE_16(index, MACRO) \ + EXPAND_RANGE_8((index), MACRO) \ + EXPAND_RANGE_8((index) + 8, MACRO) + +#define EXPAND_RANGE_32(index, MACRO) \ + EXPAND_RANGE_16((index), MACRO) \ + EXPAND_RANGE_16((index) + 16, MACRO) + +#define EXPAND_RANGE_64(index, MACRO) \ + EXPAND_RANGE_32((index), MACRO) \ + EXPAND_RANGE_32((index) + 32, MACRO) + +#define EXPAND_RANGE_128(index, MACRO) \ + EXPAND_RANGE_64((index), MACRO) \ + EXPAND_RANGE_64((index) + 64, MACRO) + +#define EXPAND_RANGE_256(index, MACRO) \ + EXPAND_RANGE_128((index), MACRO) \ + EXPAND_RANGE_128((index) + 128, MACRO) + +#define EXPAND_RANGE_512(index, MACRO) \ + EXPAND_RANGE_256((index), MACRO) \ + EXPAND_RANGE_256((index) + 256, MACRO) + +template +struct transform_constant_helper +{ + static auto decode(u32 value) { + return value; + } + + static constexpr u32 reg = index / 4; + static constexpr u8 subreg = index % 4; + + static void commit_rsx_state(rsx_state &state, u32 &&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); + } +}; + +#define TRANSFORM_CONSTANT(index) template<> struct registers_decoder : public transform_constant_helper {}; +#define DECLARE_TRANSFORM_CONSTANT(index) NV4097_SET_TRANSFORM_CONSTANT + index, + +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) + { + u32 &load = state.m_transform_program_pointer; + state.transform_program[load++] = decoded_values; + } + + static std::string dump(u32 &&decoded_values) + { + return "Transform Program (" + std::to_string(index) + "):"+ std::to_string(decoded_values); + } +}; + +template<> +struct registers_decoder +{ + static auto decode(u32 value) { + return value; + } + + static void commit_rsx_state(rsx_state &state, u32 &&decoded_values) + { + state.m_transform_program_pointer = decoded_values << 2; + } + + static std::string dump(u32 &&decoded_values) + { + return "Transform Program pointer :" + std::to_string(decoded_values); + } +}; + +#define TRANSFORM_PROGRAM(index) template<> struct registers_decoder : public transform_program_helper {}; +#define DECLARE_TRANSFORM_PROGRAM(index) NV4097_SET_TRANSFORM_PROGRAM + index, +EXPAND_RANGE_512(0, TRANSFORM_PROGRAM) + +constexpr std::integer_sequence opcode_list{}; + +} // end namespace rsx diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index f3dcec184a..48323da82d 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -5,6 +5,7 @@ #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "rsx_utils.h" +#include "rsx_decode.h" #include "Emu/Cell/PPUCallback.h" #include @@ -200,20 +201,10 @@ namespace rsx { force_inline static void impl(thread* rsxthr, u32 arg) { - method_registers.set_transform_constant(index, 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) @@ -764,6 +755,167 @@ namespace rsx } } + template + std::array fill_array(Args&& arg, std::index_sequence seq) + { + return{ T(N, std::forward(arg))... }; + } + + rsx_state::rsx_state() : + fragment_textures(fill_array(registers, std::make_index_sequence<16>())), + vertex_textures(fill_array(registers, std::make_index_sequence<4>())), + register_vertex_info(fill_array(registers, std::make_index_sequence<16>())), + vertex_arrays_info(fill_array(registers, std::make_index_sequence<16>())) + { + + } + + rsx_state::~rsx_state() + { + + } + + void rsx_state::reset() + { + //setup method registers + std::memset(registers.data(), 0, registers.size() * sizeof(u32)); + + m_primitive_type = primitive_type::triangles; + m_transform_program_pointer = 0; + + m_color_mask_r = true; + m_color_mask_g = true; + m_color_mask_b = true; + m_color_mask_a = true; + + m_scissor_width = 4096; + m_scissor_height = 4096; + m_scissor_origin_x = 0; + m_scissor_origin_y = 0; + + m_alpha_test_enabled = false; + m_alpha_func = rsx::comparaison_function::always; + m_alpha_ref = 0; + + 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; + + m_blend_color_16b_a = 0; + m_blend_color_16b_b = 0; + m_blend_color = 0; + + m_blend_equation_rgb = rsx::blend_equation::add; + m_blend_equation_a = rsx::blend_equation::add; + + m_stencil_test_enabled = false; + m_two_sided_stencil_test_enabled = false; + m_stencil_mask = 0xff; + m_stencil_func = rsx::comparaison_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; + + m_back_stencil_mask = 0xff; + m_back_stencil_func = rsx::comparaison_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; + + 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; + + // 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; + + m_depth_test_enabled = false; + m_depth_func = rsx::comparaison_function::less; + m_depth_write_enabled = true; + + 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; + + 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; + + 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::comparaison_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); + } + } + +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; + } + struct __rsx_methods_t { using rsx_impl_method_t = void(*)(u32); @@ -890,7 +1042,6 @@ namespace rsx 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 cd9b4aa495..abbeb7678b 100644 --- a/rpcs3/Emu/RSX/rsx_methods.h +++ b/rpcs3/Emu/RSX/rsx_methods.h @@ -71,12 +71,6 @@ namespace rsx } }; - template - std::array fill_array(Args&& arg, std::index_sequence seq) - { - return{ T(N, std::forward(arg))... }; - } - struct rsx_state { private: @@ -86,8 +80,9 @@ namespace rsx std::array fragment_textures; std::array vertex_textures; - std::array transform_program; + u32 m_transform_program_pointer; + std::array transform_program; std::unordered_map> transform_constants; /** @@ -110,16 +105,8 @@ namespace rsx std::array, 16> register_vertex_data; std::array vertex_arrays_info; - rsx_state() : - // unfortunatly there is no other way to fill an array with objects without default initializer - // except by using templates. - fragment_textures(fill_array(registers, std::make_index_sequence<16>())), - vertex_textures(fill_array(registers, std::make_index_sequence<4>())), - register_vertex_info(fill_array(registers, std::make_index_sequence<16>())), - vertex_arrays_info(fill_array(registers, std::make_index_sequence<16>())) - { - - } + rsx_state(); + ~rsx_state(); u32& operator[](size_t idx) { @@ -131,1047 +118,1176 @@ namespace rsx return registers[idx]; } - void reset() - { - //setup method registers - std::memset(registers.data(), 0, registers.size() * sizeof(u32)); + void decode(u32 reg, u32 value); - 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; + void reset(); - registers[NV4097_SET_ALPHA_FUNC] = CELL_GCM_ALWAYS; - registers[NV4097_SET_ALPHA_REF] = 0; + u16 m_viewport_origin_x; + u16 m_viewport_origin_y; - 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] = (CELL_GCM_FUNC_ADD << 16) | CELL_GCM_FUNC_ADD; + u16 m_viewport_width; + u16 m_viewport_height; - 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; + u16 m_scissor_origin_x; + u16 m_scissor_origin_y; - 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; + u16 m_scissor_width; + u16 m_scissor_height; - registers[NV4097_SET_SHADE_MODE] = CELL_GCM_SMOOTH; + u16 m_clear_rect_origin_x; + u16 m_clear_rect_origin_y; + u16 m_clear_rect_width; + u16 m_clear_rect_height; - registers[NV4097_SET_LOGIC_OP] = CELL_GCM_COPY; + window_origin m_shader_window_origin : 1; + window_pixel_center m_shader_window_pixel : 1; + u16 m_shader_window_height : 12; - (f32&)registers[NV4097_SET_DEPTH_BOUNDS_MIN] = 0.f; - (f32&)registers[NV4097_SET_DEPTH_BOUNDS_MAX] = 1.f; + u16 m_shader_window_offset_x; + u16 m_shader_window_offset_y; - (f32&)registers[NV4097_SET_CLIP_MIN] = 0.f; - (f32&)registers[NV4097_SET_CLIP_MAX] = 1.f; + 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; - registers[NV4097_SET_LINE_WIDTH] = 1 << 3; + rsx::shading_mode m_shading_mode : 1; - // These defaults were found using After Burner Climax (which never set fog mode despite using fog input) - 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.; + rsx::polygon_mode m_front_polygon_mode : 2; + rsx::polygon_mode m_back_polygon_mode : 2; - 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; + bool m_alpha_test_enabled : 1; + u8 m_alpha_ref; + comparaison_function m_alpha_func : 3; - registers[NV4097_SET_CLEAR_RECT_HORIZONTAL] = (4096 << 16) | 0; - registers[NV4097_SET_CLEAR_RECT_VERTICAL] = (4096 << 16) | 0; + bool m_restart_index_enabled : 1; + u32 m_restart_index; - registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffffff; + u8 m_stencil_clear_value; + u32 m_z_clear_value : 24; - registers[NV4097_SET_CONTEXT_DMA_REPORT] = CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT; - registers[NV4097_SET_TWO_SIDE_LIGHT_EN] = true; - registers[NV4097_SET_ALPHA_FUNC] = CELL_GCM_ALWAYS; + fog_mode m_fog_equation : 3; + f32 m_fog_params_0; + f32 m_fog_params_1; - // Reset vertex attrib array - for (int i = 0; i < 16; i++) - { - vertex_arrays_info[i].size = 0; - } + u8 m_index_array_location : 4; + rsx::index_array_type m_index_type : 1; + u32 m_index_array_address; - // Construct Textures - for (int i = 0; i < 16; i++) - { - fragment_textures[i].init(i); - } + u8 m_clear_color_b; + u8 m_clear_color_r; + u8 m_clear_color_g; + u8 m_clear_color_a; - for (int i = 0; i < 4; i++) - { - vertex_textures[i].init(i); - } - } + 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; + comparaison_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; + comparaison_function m_stencil_func : 3; + comparaison_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 registers[NV4097_SET_VIEWPORT_HORIZONTAL] >> 16; + return m_viewport_width; } u16 viewport_origin_x() const { - return registers[NV4097_SET_VIEWPORT_HORIZONTAL] & 0xffff; + return m_viewport_origin_x; } u16 viewport_height() const { - return registers[NV4097_SET_VIEWPORT_VERTICAL] >> 16; + return m_viewport_height; } u16 viewport_origin_y() const { - return registers[NV4097_SET_VIEWPORT_VERTICAL] & 0xffff; + return m_viewport_origin_y; } u16 scissor_origin_x() const { - return registers[NV4097_SET_SCISSOR_HORIZONTAL] & 0xffff; + return m_scissor_origin_x; } u16 scissor_width() const { - return registers[NV4097_SET_SCISSOR_HORIZONTAL] >> 16; + return m_scissor_width; } u16 scissor_origin_y() const { - return registers[NV4097_SET_SCISSOR_VERTICAL] & 0xffff; + return m_scissor_origin_y; } u16 scissor_height() const { - return registers[NV4097_SET_SCISSOR_VERTICAL] >> 16; + return m_scissor_height; } - rsx::window_origin shader_window_origin() const + window_origin shader_window_origin() const { - return rsx::to_window_origin((registers[NV4097_SET_SHADER_WINDOW] >> 12) & 0xf); + return m_shader_window_origin; } - rsx::window_pixel_center shader_window_pixel() const + window_pixel_center shader_window_pixel() const { - return rsx::to_window_pixel_center((registers[NV4097_SET_SHADER_WINDOW] >> 16) & 0xf); + return m_shader_window_pixel; } u16 shader_window_height() const { - return registers[NV4097_SET_SHADER_WINDOW] & 0xfff; + return m_shader_window_height; } - u32 shader_window_offset_x() const + u16 shader_window_offset_x() const { - return registers[NV4097_SET_WINDOW_OFFSET] & 0xffff; + return m_shader_window_offset_x; } - u32 shader_window_offset_y() const + u16 shader_window_offset_y() const { - return registers[NV4097_SET_WINDOW_OFFSET] >> 16; + return m_shader_window_offset_y; } bool depth_test_enabled() const { - return !!registers[NV4097_SET_DEPTH_TEST_ENABLE]; + return m_depth_test_enabled; } bool depth_write_enabled() const { - return !!registers[NV4097_SET_DEPTH_MASK]; + return m_depth_write_enabled; } bool alpha_test_enabled() const { - return !!registers[NV4097_SET_ALPHA_TEST_ENABLE]; + return m_alpha_test_enabled; } bool stencil_test_enabled() const { - return !!registers[NV4097_SET_STENCIL_TEST_ENABLE]; + return m_stencil_test_enabled; } bool restart_index_enabled() const { - return !!registers[NV4097_SET_RESTART_INDEX_ENABLE]; + return m_restart_index_enabled; } u32 restart_index() const { - return registers[NV4097_SET_RESTART_INDEX]; + return m_restart_index; } u32 z_clear_value() const { - return registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] >> 8; + return m_z_clear_value; } u8 stencil_clear_value() const { - return registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] & 0xff; + return m_stencil_clear_value; } f32 fog_params_0() const { - return (f32&)registers[NV4097_SET_FOG_PARAMS]; + return m_fog_params_0; } f32 fog_params_1() const { - return (f32&)registers[NV4097_SET_FOG_PARAMS + 1]; - } - - rsx::index_array_type index_type() const - { - return rsx::to_index_array_type(registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4); - } - - bool color_mask_b() const - { - return !!(registers[NV4097_SET_COLOR_MASK] & 0xff); - } - - bool color_mask_g() const - { - return !!((registers[NV4097_SET_COLOR_MASK] >> 8) & 0xff); - } - - bool color_mask_r() const - { - return !!((registers[NV4097_SET_COLOR_MASK] >> 16) & 0xff); - } - - bool color_mask_a() const - { - return !!((registers[NV4097_SET_COLOR_MASK] >> 24) & 0xff); - } - - u8 clear_color_b() const - { - return registers[NV4097_SET_COLOR_CLEAR_VALUE] & 0xff; - } - - u8 clear_color_r() const - { - return (registers[NV4097_SET_COLOR_CLEAR_VALUE] >> 16) & 0xff; - } - - u8 clear_color_g() const - { - return (registers[NV4097_SET_COLOR_CLEAR_VALUE] >> 8) & 0xff; - } - - u8 clear_color_a() const - { - return (registers[NV4097_SET_COLOR_CLEAR_VALUE] >> 24) & 0xff; - } - - bool depth_bounds_test_enabled() const - { - return !!registers[NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE]; - } - - f32 depth_bounds_min() const - { - return (f32&)registers[NV4097_SET_DEPTH_BOUNDS_MIN]; - } - - f32 depth_bounds_max() const - { - return (f32&)registers[NV4097_SET_DEPTH_BOUNDS_MAX]; - } - - f32 clip_min() const - { - return (f32&)registers[NV4097_SET_CLIP_MIN]; - } - - f32 clip_max() const - { - return (f32&)registers[NV4097_SET_CLIP_MAX]; - } - - bool logic_op_enabled() const - { - return !!registers[NV4097_SET_LOGIC_OP_ENABLE]; - } - - u8 stencil_mask() const - { - return registers[NV4097_SET_STENCIL_MASK] & 0xff; - } - - u8 back_stencil_mask() const - { - return registers[NV4097_SET_BACK_STENCIL_MASK]; - } - - bool dither_enabled() const - { - return !!registers[NV4097_SET_DITHER_ENABLE]; - } - - bool blend_enabled() const - { - return !!registers[NV4097_SET_BLEND_ENABLE]; - } - - bool blend_enabled_surface_1() const - { - return !!(registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x2); - } - - bool blend_enabled_surface_2() const - { - return !!(registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x4); - } - - bool blend_enabled_surface_3() const - { - return !!(registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x8); - } - - bool line_smooth_enabled() const - { - return !!registers[NV4097_SET_LINE_SMOOTH_ENABLE]; - } - - bool poly_offset_point_enabled() const - { - return !!registers[NV4097_SET_POLY_OFFSET_POINT_ENABLE]; - } - - bool poly_offset_line_enabled() const - { - return !!registers[NV4097_SET_POLY_OFFSET_LINE_ENABLE]; - } - - bool poly_offset_fill_enabled() const - { - return !!registers[NV4097_SET_POLY_OFFSET_FILL_ENABLE]; - } - - f32 poly_offset_scale() const - { - return (f32&)registers[NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR]; - } - - f32 poly_offset_bias() const - { - return (f32&)registers[NV4097_SET_POLYGON_OFFSET_BIAS]; - } - - bool cull_face_enabled() const - { - return !!registers[NV4097_SET_CULL_FACE_ENABLE]; - } - - bool poly_smooth_enabled() const - { - return !!registers[NV4097_SET_POLY_SMOOTH_ENABLE]; - } - - bool two_sided_stencil_test_enabled() const - { - return !!registers[NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE]; - } - - comparaison_function depth_func() const - { - return to_comparaison_function(registers[NV4097_SET_DEPTH_FUNC] & 0xffff); - } - - comparaison_function stencil_func() const - { - return to_comparaison_function(registers[NV4097_SET_STENCIL_FUNC] & 0xffff); - } - - comparaison_function back_stencil_func() const - { - return to_comparaison_function(registers[NV4097_SET_BACK_STENCIL_FUNC] & 0xffff); - } - - u8 stencil_func_ref() const - { - return registers[NV4097_SET_STENCIL_FUNC_REF]; - } - - u8 back_stencil_func_ref() const - { - return registers[NV4097_SET_BACK_STENCIL_FUNC_REF]; - } - - u8 stencil_func_mask() const - { - return registers[NV4097_SET_STENCIL_FUNC_MASK]; - } - - u8 back_stencil_func_mask() const - { - return registers[NV4097_SET_BACK_STENCIL_FUNC_MASK]; - } - - rsx::stencil_op stencil_op_fail() const - { - return to_stencil_op(registers[NV4097_SET_STENCIL_OP_FAIL] & 0xffff); - } - - rsx::stencil_op stencil_op_zfail() const - { - return to_stencil_op(registers[NV4097_SET_STENCIL_OP_ZFAIL] & 0xffff); - } - - rsx::stencil_op stencil_op_zpass() const - { - return to_stencil_op(registers[NV4097_SET_STENCIL_OP_ZPASS] & 0xffff); - } - - rsx::stencil_op back_stencil_op_fail() const - { - return to_stencil_op(registers[NV4097_SET_BACK_STENCIL_OP_FAIL] & 0xffff); - } - - rsx::stencil_op back_stencil_op_zfail() const - { - return to_stencil_op(registers[NV4097_SET_BACK_STENCIL_OP_ZFAIL] & 0xffff); - } - - rsx::stencil_op back_stencil_op_zpass() const - { - return to_stencil_op(registers[NV4097_SET_BACK_STENCIL_OP_ZPASS] & 0xffff); - } - - u8 blend_color_8b_r() const - { - return registers[NV4097_SET_BLEND_COLOR] & 0xff; - } - - u8 blend_color_8b_g() const - { - return (registers[NV4097_SET_BLEND_COLOR] >> 8) & 0xff; - } - - u8 blend_color_8b_b() const - { - return (registers[NV4097_SET_BLEND_COLOR] >> 16) & 0xff; - } - - u8 blend_color_8b_a() const - { - return (registers[NV4097_SET_BLEND_COLOR] >> 24) & 0xff; - } - - u16 blend_color_16b_r() const - { - return registers[NV4097_SET_BLEND_COLOR] & 0xffff; - } - - u16 blend_color_16b_g() const - { - return (registers[NV4097_SET_BLEND_COLOR] >> 16) & 0xffff; - } - - u16 blend_color_16b_b() const - { - return registers[NV4097_SET_BLEND_COLOR2] & 0xffff; - } - - u16 blend_color_16b_a() const - { - return (registers[NV4097_SET_BLEND_COLOR2] >> 16) & 0xffff; - } - - blend_equation blend_equation_rgb() const - { - return to_blend_equation(registers[NV4097_SET_BLEND_EQUATION] & 0xffff); - } - - blend_equation blend_equation_a() const - { - return to_blend_equation((registers[NV4097_SET_BLEND_EQUATION] >> 16) & 0xffff); - } - - blend_factor blend_func_sfactor_rgb() const - { - return to_blend_factor(registers[NV4097_SET_BLEND_FUNC_SFACTOR] & 0xffff); - } - - blend_factor blend_func_sfactor_a() const - { - return to_blend_factor((registers[NV4097_SET_BLEND_FUNC_SFACTOR] >> 16) & 0xffff); - } - - blend_factor blend_func_dfactor_rgb() const - { - return to_blend_factor(registers[NV4097_SET_BLEND_FUNC_DFACTOR] & 0xffff); - } - - blend_factor blend_func_dfactor_a() const - { - return to_blend_factor((registers[NV4097_SET_BLEND_FUNC_DFACTOR] >> 16) & 0xffff); - } - - logic_op logic_operation() const - { - return to_logic_op(registers[NV4097_SET_LOGIC_OP]); - } - - user_clip_plane_op clip_plane_0_enabled() const - { - return to_user_clip_plane_op(registers[NV4097_SET_USER_CLIP_PLANE_CONTROL] & 0xf); - } - - user_clip_plane_op clip_plane_1_enabled() const - { - return to_user_clip_plane_op((registers[NV4097_SET_USER_CLIP_PLANE_CONTROL] >> 4) & 0xf); - } - - user_clip_plane_op clip_plane_2_enabled() const - { - return to_user_clip_plane_op((registers[NV4097_SET_USER_CLIP_PLANE_CONTROL] >> 8) & 0xf); - } - - user_clip_plane_op clip_plane_3_enabled() const - { - return to_user_clip_plane_op((registers[NV4097_SET_USER_CLIP_PLANE_CONTROL] >> 12) & 0xf); - } - - user_clip_plane_op clip_plane_4_enabled() const - { - return to_user_clip_plane_op((registers[NV4097_SET_USER_CLIP_PLANE_CONTROL] >> 16) & 0xf); - } - - user_clip_plane_op clip_plane_5_enabled() const - { - return to_user_clip_plane_op((registers[NV4097_SET_USER_CLIP_PLANE_CONTROL] >> 20) & 0xf); - } - - front_face front_face_mode() const - { - return to_front_face(registers[NV4097_SET_FRONT_FACE] & 0xffff); - } - - cull_face cull_face_mode() const - { - return to_cull_face(registers[NV4097_SET_CULL_FACE] & 0xffff); - } - - f32 line_width() const - { - u32 line_width = registers[NV4097_SET_LINE_WIDTH]; - return (line_width >> 3) + (line_width & 7) / 8.f; - } - - u8 alpha_ref() const - { - return registers[NV4097_SET_ALPHA_REF] & 0xff; - } - - surface_target surface_color_target() - { - return rsx::to_surface_target(registers[NV4097_SET_SURFACE_COLOR_TARGET] & 0xff); - } - - u16 surface_clip_origin_x() const - { - return (registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] & 0xffff); - } - - u16 surface_clip_width() const - { - return ((registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16) & 0xffff); - } - - u16 surface_clip_origin_y() const - { - return (registers[NV4097_SET_SURFACE_CLIP_VERTICAL] & 0xffff); - } - - u16 surface_clip_height() const - { - return ((registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16) & 0xffff); - } - - u32 surface_a_offset() const - { - return registers[NV4097_SET_SURFACE_COLOR_AOFFSET]; - } - - u32 surface_b_offset() const - { - return registers[NV4097_SET_SURFACE_COLOR_BOFFSET]; - } - - u32 surface_c_offset() const - { - return registers[NV4097_SET_SURFACE_COLOR_COFFSET]; - } - - u32 surface_d_offset() const - { - return registers[NV4097_SET_SURFACE_COLOR_DOFFSET]; - } - - u32 surface_a_pitch() const - { - return registers[NV4097_SET_SURFACE_PITCH_A]; - } - - u32 surface_b_pitch() const - { - return registers[NV4097_SET_SURFACE_PITCH_B]; - } - - u32 surface_c_pitch() const - { - return registers[NV4097_SET_SURFACE_PITCH_C]; - } - - u32 surface_d_pitch() const - { - return registers[NV4097_SET_SURFACE_PITCH_D]; - } - - u32 surface_a_dma() const - { - return registers[NV4097_SET_CONTEXT_DMA_COLOR_A]; - } - - u32 surface_b_dma() const - { - return registers[NV4097_SET_CONTEXT_DMA_COLOR_B]; - } - - u32 surface_c_dma() const - { - return registers[NV4097_SET_CONTEXT_DMA_COLOR_C]; - } - - u32 surface_d_dma() const - { - return registers[NV4097_SET_CONTEXT_DMA_COLOR_D]; - } - - u32 surface_z_offset() const - { - return registers[NV4097_SET_SURFACE_ZETA_OFFSET]; - } - - u32 surface_z_pitch() const - { - return registers[NV4097_SET_SURFACE_PITCH_Z]; - } - - u32 surface_z_dma() const - { - return registers[NV4097_SET_CONTEXT_DMA_ZETA]; - } - - f32 viewport_scale_x() const - { - return (f32&)registers[NV4097_SET_VIEWPORT_SCALE]; - } - - f32 viewport_scale_y() const - { - return (f32&)registers[NV4097_SET_VIEWPORT_SCALE + 1]; - } - - f32 viewport_scale_z() const - { - return (f32&)registers[NV4097_SET_VIEWPORT_SCALE + 2]; - } - - f32 viewport_scale_w() const - { - return (f32&)registers[NV4097_SET_VIEWPORT_SCALE + 3]; - } - - f32 viewport_offset_x() const - { - return (f32&)registers[NV4097_SET_VIEWPORT_OFFSET]; - } - - f32 viewport_offset_y() const - { - return (f32&)registers[NV4097_SET_VIEWPORT_OFFSET + 1]; - } - - f32 viewport_offset_z() const - { - return (f32&)registers[NV4097_SET_VIEWPORT_OFFSET + 2]; - } - - f32 viewport_offset_w() const - { - return (f32&)registers[NV4097_SET_VIEWPORT_OFFSET + 3]; - } - - bool two_side_light_en() const - { - return !!registers[NV4097_SET_TWO_SIDE_LIGHT_EN]; - } - - rsx::fog_mode fog_equation() const - { - return rsx::to_fog_mode(registers[NV4097_SET_FOG_MODE]); - } - - rsx::comparaison_function alpha_func() const - { - return to_comparaison_function(registers[NV4097_SET_ALPHA_FUNC]); - } - - u16 vertex_attrib_input_mask() const - { - return registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK] & 0xffff; - } - - u16 frequency_divider_operation_mask() const - { - return registers[NV4097_SET_FREQUENCY_DIVIDER_OPERATION] & 0xffff; - } - - u32 vertex_attrib_output_mask() const - { - return registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK]; - } - - // Quite opaque - u32 shader_control() const - { - return registers[NV4097_SET_SHADER_CONTROL]; - } - - surface_color_format surface_color() const - { - return to_surface_color_format(registers[NV4097_SET_SURFACE_FORMAT] & 0x1f); - } - - surface_depth_format surface_depth_fmt() const - { - return to_surface_depth_format((registers[NV4097_SET_SURFACE_FORMAT] >> 5) & 0x7); - } - - surface_antialiasing surface_antialias() const - { - return to_surface_antialiasing((registers[NV4097_SET_SURFACE_FORMAT] >> 12) & 0xf); - } - - u8 surface_log2_height() const - { - return (registers[NV4097_SET_SURFACE_FORMAT] >> 24) & 0xff; - } - - u8 surface_log2_width() const - { - return (registers[NV4097_SET_SURFACE_FORMAT] >> 16) & 0xff; - } - - u32 vertex_data_base_offset() const - { - return registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET]; - } - - u32 index_array_address() const - { - return registers[NV4097_SET_INDEX_ARRAY_ADDRESS]; + return m_fog_params_1; } u8 index_array_location() const { - return registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf; + return m_index_array_location; + } + + rsx::index_array_type index_type() const + { + return m_index_type; + } + + bool color_mask_b() const + { + return m_color_mask_b; + } + + bool color_mask_g() const + { + return m_color_mask_g; + } + + bool color_mask_r() const + { + return m_color_mask_r; + } + + bool color_mask_a() const + { + return m_color_mask_a; + } + + u8 clear_color_b() const + { + return m_clear_color_b; + } + + u8 clear_color_r() const + { + return m_clear_color_r; + } + + u8 clear_color_g() const + { + return m_clear_color_g; + } + + u8 clear_color_a() const + { + return m_clear_color_a; + } + + bool depth_bounds_test_enabled() const + { + return m_depth_bounds_test_enabled; + } + + f32 depth_bounds_min() const + { + return m_depth_bounds_min; + } + + f32 depth_bounds_max() const + { + return m_depth_bounds_max; + } + + f32 clip_min() const + { + return m_clip_min; + } + + f32 clip_max() const + { + return m_clip_max; + } + + bool logic_op_enabled() const + { + return m_logic_op_enabled; + } + + u8 stencil_mask() const + { + return m_stencil_mask; + } + + u8 back_stencil_mask() const + { + return m_back_stencil_mask; + } + + bool dither_enabled() const + { + return m_dither_enabled; + } + + bool blend_enabled() const + { + return m_blend_enabled; + } + + bool blend_enabled_surface_1() const + { + return m_blend_enabled_surface_1; + } + + bool blend_enabled_surface_2() const + { + return m_blend_enabled_surface_2; + } + + bool blend_enabled_surface_3() const + { + return m_blend_enabled_surface_3; + } + + bool line_smooth_enabled() const + { + return m_line_smooth_enabled; + } + + bool poly_offset_point_enabled() const + { + return m_poly_offset_point_enabled; + } + + bool poly_offset_line_enabled() const + { + return m_offset_line_enabled; + } + + bool poly_offset_fill_enabled() const + { + return m_poly_offset_fill_enabled; + } + + f32 poly_offset_scale() const + { + return m_poly_offset_scale; + } + + f32 poly_offset_bias() const + { + return m_poly_offset_bias; + } + + bool cull_face_enabled() const + { + return m_cull_face_enabled; + } + + bool poly_smooth_enabled() const + { + return m_poly_smooth_enabled; + } + + bool two_sided_stencil_test_enabled() const + { + return m_two_sided_stencil_test_enabled; + } + + comparaison_function depth_func() const + { + return m_depth_func; + } + + comparaison_function stencil_func() const + { + return m_stencil_func; + } + + comparaison_function back_stencil_func() const + { + return m_back_stencil_func; + } + + u8 stencil_func_ref() const + { + return m_stencil_func_ref; + } + + u8 back_stencil_func_ref() const + { + return m_back_stencil_func_ref; + } + + u8 stencil_func_mask() const + { + return m_stencil_func_mask; + } + + u8 back_stencil_func_mask() const + { + return m_back_stencil_func_mask; + } + + stencil_op stencil_op_fail() const + { + return m_stencil_op_fail; + } + + stencil_op stencil_op_zfail() const + { + return m_stencil_op_zfail; + } + + stencil_op stencil_op_zpass() const + { + return m_stencil_op_zpass; + } + + stencil_op back_stencil_op_fail() const + { + return m_back_stencil_op_fail; + } + + rsx::stencil_op back_stencil_op_zfail() const + { + return m_back_stencil_op_zfail; + } + + rsx::stencil_op back_stencil_op_zpass() const + { + return m_back_stencil_op_zpass; + } + + u8 blend_color_8b_r() const + { + return m_blend_color & 0xff; + } + + u8 blend_color_8b_g() const + { + return (m_blend_color >> 8) & 0xff; + } + + u8 blend_color_8b_b() const + { + return (m_blend_color >> 16) & 0xff; + } + + u8 blend_color_8b_a() const + { + return (m_blend_color >> 24) & 0xff; + } + + u16 blend_color_16b_r() const + { + return m_blend_color & 0xffff; + } + + u16 blend_color_16b_g() const + { + return (m_blend_color >> 16) & 0xffff; + } + + u16 blend_color_16b_b() const + { + return m_blend_color_16b_b; + } + + u16 blend_color_16b_a() const + { + return m_blend_color_16b_a; + } + + blend_equation blend_equation_rgb() const + { + return m_blend_equation_rgb; + } + + blend_equation blend_equation_a() const + { + return m_blend_equation_a; + } + + blend_factor blend_func_sfactor_rgb() const + { + return m_blend_func_sfactor_rgb; + } + + blend_factor blend_func_sfactor_a() const + { + return m_blend_func_sfactor_a; + } + + blend_factor blend_func_dfactor_rgb() const + { + return m_blend_func_dfactor_rgb; + } + + blend_factor blend_func_dfactor_a() const + { + return m_blend_func_dfactor_a; + } + + logic_op logic_operation() const + { + return m_logic_operation; + } + + user_clip_plane_op clip_plane_0_enabled() const + { + return m_clip_plane_0_enabled; + } + + user_clip_plane_op clip_plane_1_enabled() const + { + return m_clip_plane_1_enabled; + } + + user_clip_plane_op clip_plane_2_enabled() const + { + return m_clip_plane_2_enabled; + } + + user_clip_plane_op clip_plane_3_enabled() const + { + return m_clip_plane_3_enabled; + } + + user_clip_plane_op clip_plane_4_enabled() const + { + return m_clip_plane_4_enabled; + } + + user_clip_plane_op clip_plane_5_enabled() const + { + return m_clip_plane_5_enabled; + } + + front_face front_face_mode() const + { + return m_front_face_mode; + } + + cull_face cull_face_mode() const + { + return m_cull_face_mode; + } + + f32 line_width() const + { + return m_line_width; + } + + u8 alpha_ref() const + { + return m_alpha_ref; + } + + surface_target surface_color_target() + { + return m_surface_color_target; + } + + u16 surface_clip_origin_x() const + { + return m_surface_clip_origin_x; + } + + u16 surface_clip_width() const + { + return m_surface_clip_width; + } + + u16 surface_clip_origin_y() const + { + return m_surface_clip_origin_y; + } + + u16 surface_clip_height() const + { + return m_surface_clip_height; + } + + u32 surface_a_offset() const + { + return m_surface_a_offset; + } + + u32 surface_b_offset() const + { + return m_surface_b_offset; + } + + u32 surface_c_offset() const + { + return m_surface_c_offset; + } + + u32 surface_d_offset() const + { + return m_surface_d_offset; + } + + u32 surface_a_pitch() const + { + return m_surface_a_pitch; + } + + u32 surface_b_pitch() const + { + return m_surface_b_pitch; + } + + u32 surface_c_pitch() const + { + return m_surface_c_pitch; + } + + u32 surface_d_pitch() const + { + return m_surface_d_pitch; + } + + u32 surface_a_dma() const + { + return m_surface_a_dma; + } + + u32 surface_b_dma() const + { + return m_surface_b_dma; + } + + u32 surface_c_dma() const + { + return m_surface_c_dma; + } + + u32 surface_d_dma() const + { + return m_surface_d_dma; + } + + u32 surface_z_offset() const + { + return m_surface_z_offset; + } + + u32 surface_z_pitch() const + { + return m_surface_z_pitch; + } + + u32 surface_z_dma() const + { + return m_surface_z_dma; + } + + f32 viewport_scale_x() const + { + return m_viewport_scale_x; + } + + f32 viewport_scale_y() const + { + return m_viewport_scale_y; + } + + f32 viewport_scale_z() const + { + return m_viewport_scale_z; + } + + f32 viewport_scale_w() const + { + return m_viewport_scale_w; + } + + f32 viewport_offset_x() const + { + return m_viewport_offset_x; + } + + f32 viewport_offset_y() const + { + return m_viewport_offset_y; + } + + f32 viewport_offset_z() const + { + return m_viewport_offset_z; + } + + f32 viewport_offset_w() const + { + return m_viewport_offset_w; + } + + bool two_side_light_en() const + { + return m_two_side_light_enabled; + } + + fog_mode fog_equation() const + { + return m_fog_equation; + } + + comparaison_function alpha_func() const + { + return m_alpha_func; + } + + u16 vertex_attrib_input_mask() const + { + return m_vertex_attrib_input_mask; + } + + u16 frequency_divider_operation_mask() const + { + return m_frequency_divider_operation_mask; + } + + u32 vertex_attrib_output_mask() const + { + return m_vertex_attrib_output_mask; + } + + u32 shader_control() const + { + return m_shader_control; + } + + surface_color_format surface_color() const + { + return m_surface_color; + } + + surface_depth_format surface_depth_fmt() const + { + return m_surface_depth_format; + } + + surface_antialiasing surface_antialias() const + { + return m_surface_antialias; + } + + u8 surface_log2_height() const + { + return m_surface_log2_height; + } + + u8 surface_log2_width() const + { + return m_surface_log2_width; + } + + u32 vertex_data_base_offset() const + { + return m_vertex_data_base_offset; + } + + u32 index_array_address() const + { + return m_index_array_address; } u32 vertex_data_base_index() const { - return registers[NV4097_SET_VERTEX_DATA_BASE_INDEX]; + return m_vertex_data_base_index; } u32 shader_program_address() const { - return registers[NV4097_SET_SHADER_PROGRAM]; + return m_shader_program_address; } u32 transform_program_start() const { - return registers[NV4097_SET_TRANSFORM_PROGRAM_START]; + return m_transform_program_start; } primitive_type primitive_mode() const { - return to_primitive_type(registers[NV4097_SET_BEGIN_END]); + return m_primitive_type; } u32 semaphore_offset_406e() const { - return registers[NV406E_SEMAPHORE_OFFSET]; + return m_semaphore_offset_406e; } u32 semaphore_offset_4097() const { - return registers[NV4097_SET_SEMAPHORE_OFFSET]; + return m_semaphore_offset_4097; } blit_engine::context_dma context_dma_report() const { - return blit_engine::to_context_dma(registers[NV4097_SET_CONTEXT_DMA_REPORT]); + return m_context_dma_report; } blit_engine::transfer_operation blit_engine_operation() const { - return blit_engine::to_transfer_operation(registers[NV3089_SET_OPERATION]); + return m_blit_engine_operation; } /// TODO: find the purpose vs in/out equivalents u16 blit_engine_clip_x() const { - return registers[NV3089_CLIP_POINT] & 0xffff; + return m_blit_engine_clip_x; } u16 blit_engine_clip_y() const { - return registers[NV3089_CLIP_POINT] >> 16; + return m_blit_engine_clip_y; } u16 blit_engine_clip_width() const { - return registers[NV3089_CLIP_SIZE] & 0xffff; + return m_blit_engine_width; } u16 blit_engine_clip_height() const { - return registers[NV3089_CLIP_SIZE] >> 16; + return m_blit_engine_height; } u16 blit_engine_output_x() const { - return registers[NV3089_IMAGE_OUT_POINT] & 0xffff; + return m_blit_engine_output_x; } u16 blit_engine_output_y() const { - return registers[NV3089_IMAGE_OUT_POINT] >> 16; + return m_blit_engine_output_y; } u16 blit_engine_output_width() const { - return registers[NV3089_IMAGE_OUT_SIZE] & 0xffff; + return m_blit_engine_output_width; } u16 blit_engine_output_height() const { - return registers[NV3089_IMAGE_OUT_SIZE] >> 16; + return m_blit_engine_output_height; } // there is no x/y ? u16 blit_engine_input_width() const { - return registers[NV3089_IMAGE_IN_SIZE] & 0xffff; + return m_blit_engine_input_width; } u16 blit_engine_input_height() const { - return registers[NV3089_IMAGE_IN_SIZE] >> 16; + return m_blit_engine_input_height; } u16 blit_engine_input_pitch() const { - return registers[NV3089_IMAGE_IN_FORMAT] & 0xffff; + return m_blit_engine_input_pitch; } blit_engine::transfer_origin blit_engine_input_origin() const { - return blit_engine::to_transfer_origin((registers[NV3089_IMAGE_IN_FORMAT] >> 16) & 0xff); + return m_blit_engine_input_origin; } blit_engine::transfer_interpolator blit_engine_input_inter() const { - return blit_engine::to_transfer_interpolator((registers[NV3089_IMAGE_IN_FORMAT] >> 24) & 0xff); + return m_blit_engine_input_inter; } blit_engine::transfer_source_format blit_engine_src_color_format() const { - return blit_engine::to_transfer_source_format(registers[NV3089_SET_COLOR_FORMAT]); + return m_blit_engine_src_color_format; } // ??? f32 blit_engine_in_x() const { - return (registers[NV3089_IMAGE_IN] & 0xffff) / 16.f; + return m_blit_engine_in_x / 16.f; } // ??? f32 blit_engine_in_y() const { - return (registers[NV3089_IMAGE_IN] >> 16) / 16.f; + return m_blit_engine_in_y / 16.f; } u32 blit_engine_input_offset() const { - return registers[NV3089_IMAGE_IN_OFFSET]; + return m_blit_engine_input_offset; } u32 blit_engine_input_location() const { - return registers[NV3089_SET_CONTEXT_DMA_IMAGE]; + return m_blit_engine_input_location; } blit_engine::context_surface blit_engine_context_surface() const { - return blit_engine::to_context_surface(registers[NV3089_SET_CONTEXT_SURFACE]); + return m_blit_engine_context_surface; } u32 blit_engine_output_location_nv3062() const { - return registers[NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN]; + return m_blit_engine_output_location_nv3062; } u32 blit_engine_output_offset_nv3062() const { - return registers[NV3062_SET_OFFSET_DESTIN]; + return m_blit_engine_output_offset_nv3062; } blit_engine::transfer_destination_format blit_engine_nv3062_color_format() const { - return rsx::blit_engine::to_transfer_destination_format(registers[NV3062_SET_COLOR_FORMAT]); + return m_blit_engine_nv3062_color_format; } u16 blit_engine_output_alignment_nv3062() const { - return registers[NV3062_SET_PITCH] & 0xffff; + return m_blit_engine_output_alignement_nv3062; } u16 blit_engine_output_pitch_nv3062() const { - return registers[NV3062_SET_PITCH] >> 16; + return m_blit_engine_output_pitch_nv3062; } u32 blit_engine_nv309E_location() const { - return registers[NV309E_SET_CONTEXT_DMA_IMAGE]; + return m_blit_engine_nv309E_location; } u32 blit_engine_nv309E_offset() const { - return registers[NV309E_SET_OFFSET]; + return m_blit_engine_nv309E_offset; } blit_engine::transfer_destination_format blit_engine_output_format_nv309E() const { - return rsx::blit_engine::to_transfer_destination_format(registers[NV309E_SET_FORMAT]); + return m_blit_engine_output_format_nv309E; } u32 blit_engine_ds_dx() const { - return registers[NV3089_DS_DX]; + return m_blit_engine_ds_dx; } u32 blit_engine_dt_dy() const { - return registers[NV3089_DT_DY]; + return m_blit_engine_dt_dy; } u8 nv309e_sw_width_log2() const { - return (registers[NV309E_SET_FORMAT] >> 16) & 0xff; + return m_nv309e_sw_width_log2; } u8 nv309e_sw_height_log2() const { - return (registers[NV309E_SET_FORMAT] >> 24) & 0xff; + return m_nv309e_sw_height_log2; } u32 nv0039_input_pitch() const { - return registers[NV0039_PITCH_IN]; + return m_nv0039_input_pitch; } u32 nv0039_output_pitch() const { - return registers[NV0039_PITCH_OUT]; + return m_nv0039_output_pitch; } u32 nv0039_line_length() const { - return registers[NV0039_LINE_LENGTH_IN]; + return m_nv0039_line_length; } u32 nv0039_line_count() const { - return registers[NV0039_LINE_COUNT]; + return m_nv0039_line_count; } u8 nv0039_output_format() const { - return (registers[NV0039_FORMAT] >> 8) & 0xff; + return m_nv0039_output_format; } u8 nv0039_input_format() const { - return registers[NV0039_FORMAT] & 0xff; + return m_nv0039_input_format; } u32 nv0039_output_offset() const { - return registers[NV0039_OFFSET_OUT]; + return m_nv0039_output_offset; } u32 nv0039_output_location() { - return registers[NV0039_SET_CONTEXT_DMA_BUFFER_OUT]; + return m_nv0039_output_location; } u32 nv0039_input_offset() const { - return registers[NV0039_OFFSET_IN]; + return m_nv0039_input_offset; } u32 nv0039_input_location() const { - return registers[NV0039_SET_CONTEXT_DMA_BUFFER_IN]; - } - - 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++; - } - - void set_transform_constant(u32 index, u32 constant) - { - u32 load = registers[NV4097_SET_TRANSFORM_CONSTANT_LOAD]; - u32 reg = index / 4; - u32 subreg = index % 4; - transform_constants[load + reg].rgba[subreg] = (f32&)constant; + return m_nv0039_input_location; } u16 nv308a_x() const { - return registers[NV308A_POINT] & 0xffff; + return m_nv308a_x; } u16 nv308a_y() const { - return registers[NV308A_POINT] >> 16; + return m_nv308a_y; } }; diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 63889b31ae..7a9b28ad9e 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -600,6 +600,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index b51c8967b4..69e679e9d1 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1690,5 +1690,8 @@ Emu\GPU\RSX + + Emu\GPU\RSX + \ No newline at end of file