rsx: Gather most rsx commands pretty printing and state modification function in a single file.

rsx_decode.h implements a "rsx_decoders" template class that is specialized for most GCM command
found in rsx command buffer. 3 static members are defined : a "decode" function that turns command
value into a more meaninfull type if applicable (for instance bool for _enabled* command, surface
formats for set_surface_format command...), a "commit_rsx_state" that modifies a given rsx_state
structure when the command is parsed, and a "dump" function used in rsx_debugger for pretty printing.
Hopefully having the 3 functions in a single place for every command will act as a self documenting
list of rsx command buffer opcode.

rsx_state is also expanded into several explicit variables instead of being stored into a u32 array.
This should makes debugging easier (Visual Studio will display the exact value of these member for instance)
as well as preparing rsx_state for serialisation/deserialisation.

The vertex array and textures opcode are not concerned atm for bisecting purpose.
This commit is contained in:
Vincent Lejeune 2016-07-05 19:05:45 +02:00
parent 692d9dd4ae
commit d97cdb9fbf
8 changed files with 3990 additions and 1250 deletions

File diff suppressed because it is too large Load Diff

View File

@ -48,6 +48,7 @@ namespace rsx
enum class primitive_type : u8 enum class primitive_type : u8
{ {
invalid,
points, points,
lines, lines,
line_loop, // line strip with last end being joined with first end. 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); 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 namespace blit_engine
{ {
enum class transfer_origin : u8 enum class transfer_origin : u8
@ -410,12 +428,6 @@ enum CellRescTableElement
CELL_RESC_ELEMENT_FLOAT = 1, CELL_RESC_ELEMENT_FLOAT = 1,
}; };
enum
{
CELL_GCM_FLAT = 0x1D00,
CELL_GCM_SMOOTH = 0x1D01,
};
enum enum
{ {
CELL_GCM_SYSTEM_MODE_IOMAP_512MB = 1, CELL_GCM_SYSTEM_MODE_IOMAP_512MB = 1,
@ -563,28 +575,6 @@ enum
CELL_GCM_ZERO = 0, CELL_GCM_ZERO = 0,
CELL_GCM_ONE = 1, 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_FRONT = 0x0404,
CELL_GCM_BACK = 0x0405, CELL_GCM_BACK = 0x0405,
@ -593,30 +583,6 @@ enum
CELL_GCM_CW = 0x0900, CELL_GCM_CW = 0x0900,
CELL_GCM_CCW = 0x0901, 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_LOCAL_TO_LOCAL = 0,
CELL_GCM_TRANSFER_MAIN_TO_LOCAL = 1, CELL_GCM_TRANSFER_MAIN_TO_LOCAL = 1,
CELL_GCM_TRANSFER_LOCAL_TO_MAIN = 2, 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_TEX6 = 1 << CELL_GCM_ATTRIB_OUTPUT_TEX6,
CELL_GCM_ATTRIB_OUTPUT_MASK_TEX7 = 1 << CELL_GCM_ATTRIB_OUTPUT_TEX7, 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_TRUE = 1,
CELL_GCM_FALSE = 0, CELL_GCM_FALSE = 0,
}; };

View File

@ -468,7 +468,7 @@ namespace rsx
//LOG_NOTICE(RSX, "%s(0x%x) = 0x%x", get_method_name(reg).c_str(), reg, value); //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) if (capture_current_frame)
{ {

2472
rpcs3/Emu/RSX/rsx_decode.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@
#include "Emu/Memory/Memory.h" #include "Emu/Memory/Memory.h"
#include "Emu/System.h" #include "Emu/System.h"
#include "rsx_utils.h" #include "rsx_utils.h"
#include "rsx_decode.h"
#include "Emu/Cell/PPUCallback.h" #include "Emu/Cell/PPUCallback.h"
#include <thread> #include <thread>
@ -200,20 +201,10 @@ namespace rsx
{ {
force_inline static void impl(thread* rsxthr, u32 arg) force_inline static void impl(thread* rsxthr, u32 arg)
{ {
method_registers.set_transform_constant(index, arg);
rsxthr->m_transform_constants_dirty = true; rsxthr->m_transform_constants_dirty = true;
} }
}; };
template<u32 index>
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) force_inline void set_begin_end(thread* rsxthr, u32 arg)
{ {
if (arg) if (arg)
@ -764,6 +755,167 @@ namespace rsx
} }
} }
template<typename T, size_t... N, typename Args>
std::array<T, sizeof...(N)> fill_array(Args&& arg, std::index_sequence<N...> seq)
{
return{ T(N, std::forward<Args>(arg))... };
}
rsx_state::rsx_state() :
fragment_textures(fill_array<texture>(registers, std::make_index_sequence<16>())),
vertex_textures(fill_array<vertex_texture>(registers, std::make_index_sequence<4>())),
register_vertex_info(fill_array<data_array_format_info>(registers, std::make_index_sequence<16>())),
vertex_arrays_info(fill_array<data_array_format_info>(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<u32... opcode>
auto create_commit_functions_table(const std::integer_sequence<u32, opcode...> &)
{
return std::unordered_map<uint32_t, void(*)(rsx_state&, u32)>{ {opcode, commit<opcode>}... };
}
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 struct __rsx_methods_t
{ {
using rsx_impl_method_t = void(*)(u32); using rsx_impl_method_t = void(*)(u32);
@ -890,7 +1042,6 @@ namespace rsx
bind_range<NV4097_SET_VERTEX_DATA2S_M, 1, 16, nv4097::set_vertex_data2s_m>(); bind_range<NV4097_SET_VERTEX_DATA2S_M, 1, 16, nv4097::set_vertex_data2s_m>();
bind_range<NV4097_SET_VERTEX_DATA4S_M + 1, 2, 16, nv4097::set_vertex_data4s_m>(); bind_range<NV4097_SET_VERTEX_DATA4S_M + 1, 2, 16, nv4097::set_vertex_data4s_m>();
bind_range<NV4097_SET_TRANSFORM_CONSTANT, 1, 32, nv4097::set_transform_constant>(); bind_range<NV4097_SET_TRANSFORM_CONSTANT, 1, 32, nv4097::set_transform_constant>();
bind_range<NV4097_SET_TRANSFORM_PROGRAM + 3, 4, 128, nv4097::set_transform_program>();
bind_cpu_only<NV4097_GET_REPORT, nv4097::get_report>(); bind_cpu_only<NV4097_GET_REPORT, nv4097::get_report>();
bind_cpu_only<NV4097_CLEAR_REPORT_VALUE, nv4097::clear_report_value>(); bind_cpu_only<NV4097_CLEAR_REPORT_VALUE, nv4097::clear_report_value>();
bind<NV4097_SET_SURFACE_CLIP_HORIZONTAL, nv4097::set_surface_dirty_bit>(); bind<NV4097_SET_SURFACE_CLIP_HORIZONTAL, nv4097::set_surface_dirty_bit>();

File diff suppressed because it is too large Load Diff

View File

@ -600,6 +600,7 @@
<ClInclude Include="Emu\DbgCommand.h" /> <ClInclude Include="Emu\DbgCommand.h" />
<ClInclude Include="Emu\Memory\wait_engine.h" /> <ClInclude Include="Emu\Memory\wait_engine.h" />
<ClInclude Include="Emu\RSX\rsx_cache.h" /> <ClInclude Include="Emu\RSX\rsx_cache.h" />
<ClInclude Include="Emu\RSX\rsx_decode.h" />
<ClInclude Include="Emu\RSX\rsx_vertex_data.h" /> <ClInclude Include="Emu\RSX\rsx_vertex_data.h" />
<ClInclude Include="Emu\VFS.h" /> <ClInclude Include="Emu\VFS.h" />
<ClInclude Include="Emu\GameInfo.h" /> <ClInclude Include="Emu\GameInfo.h" />

View File

@ -1690,5 +1690,8 @@
<ClInclude Include="Emu\RSX\rsx_vertex_data.h"> <ClInclude Include="Emu\RSX\rsx_vertex_data.h">
<Filter>Emu\GPU\RSX</Filter> <Filter>Emu\GPU\RSX</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Emu\RSX\rsx_decode.h">
<Filter>Emu\GPU\RSX</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>