From 772706ca4cce840be2daf704e6fd81a43a2b15b9 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 26 Jun 2016 23:37:02 +0200 Subject: [PATCH] Factorize rsx state --- rpcs3/Emu/RSX/Common/BufferUtils.cpp | 26 +- rpcs3/Emu/RSX/Common/surface_store.h | 13 +- rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp | 32 +- rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp | 183 ++- rpcs3/Emu/RSX/D3D12/D3D12Formats.h | 18 +- rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp | 19 +- rpcs3/Emu/RSX/D3D12/D3D12GSRender.h | 2 - rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp | 136 +- rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp | 132 +- rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp | 33 +- rpcs3/Emu/RSX/GCM.cpp | 254 ++++ rpcs3/Emu/RSX/GCM.h | 219 +++- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 374 +++--- rpcs3/Emu/RSX/GL/gl_render_targets.cpp | 103 +- rpcs3/Emu/RSX/GL/gl_render_targets.h | 24 - rpcs3/Emu/RSX/GL/vertex_buffer.cpp | 24 +- rpcs3/Emu/RSX/RSXTexture.cpp | 170 +-- rpcs3/Emu/RSX/RSXTexture.h | 8 + rpcs3/Emu/RSX/RSXThread.cpp | 242 ++-- rpcs3/Emu/RSX/RSXThread.h | 43 - rpcs3/Emu/RSX/VK/VKFormats.h | 6 +- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 394 +++--- rpcs3/Emu/RSX/VK/VKGSRender.h | 2 - rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp | 22 +- rpcs3/Emu/RSX/rsx_methods.cpp | 188 ++- rpcs3/Emu/RSX/rsx_methods.h | 1114 ++++++++++++++++- rpcs3/Emu/RSX/rsx_utils.cpp | 24 +- rpcs3/Emu/RSX/rsx_vertex_data.h | 40 + rpcs3/Gui/RSXDebugger.cpp | 12 +- rpcs3/emucore.vcxproj | 1 + rpcs3/emucore.vcxproj.filters | 3 + 31 files changed, 2662 insertions(+), 1199 deletions(-) create mode 100644 rpcs3/Emu/RSX/rsx_vertex_data.h diff --git a/rpcs3/Emu/RSX/Common/BufferUtils.cpp b/rpcs3/Emu/RSX/Common/BufferUtils.cpp index b278851f41..ae543cd45c 100644 --- a/rpcs3/Emu/RSX/Common/BufferUtils.cpp +++ b/rpcs3/Emu/RSX/Common/BufferUtils.cpp @@ -347,16 +347,16 @@ void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, template std::tuple write_index_array_data_to_buffer_impl(gsl::span dst, rsx::primitive_type draw_mode, const std::vector > &first_count_arguments) { - u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_INDEX_ARRAY_ADDRESS], rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf); - rsx::index_array_type type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4); + u32 address = rsx::get_address(rsx::method_registers.index_array_address(), rsx::method_registers.index_array_location()); + rsx::index_array_type type = rsx::method_registers.index_type(); u32 type_size = gsl::narrow(get_index_type_size(type)); - EXPECTS(rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX] == 0); + EXPECTS(rsx::method_registers.vertex_data_base_index() == 0); - bool is_primitive_restart_enabled = !!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE]; - u32 primitive_restart_index = rsx::method_registers[NV4097_SET_RESTART_INDEX]; + bool is_primitive_restart_enabled = rsx::method_registers.restart_index_enabled(); + u32 primitive_restart_index = rsx::method_registers.restart_index(); // Disjoint first_counts ranges not supported atm for (int i = 0; i < first_count_arguments.size() - 1; i++) @@ -403,12 +403,12 @@ std::tuple write_index_array_data_to_buffer(gsl::span dst, std::tuple write_index_array_data_to_buffer_untouched(gsl::span dst, const std::vector > &first_count_arguments) { - u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_INDEX_ARRAY_ADDRESS], rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf); - rsx::index_array_type type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4); + u32 address = rsx::get_address(rsx::method_registers.index_array_address(), rsx::method_registers.index_array_location()); + rsx::index_array_type type = rsx::method_registers.index_type(); u32 type_size = gsl::narrow(get_index_type_size(type)); - bool is_primitive_restart_enabled = !!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE]; - u32 primitive_restart_index = rsx::method_registers[NV4097_SET_RESTART_INDEX]; + bool is_primitive_restart_enabled = rsx::method_registers.restart_index_enabled(); + u32 primitive_restart_index = rsx::method_registers.restart_index(); // Disjoint first_counts ranges not supported atm for (int i = 0; i < first_count_arguments.size() - 1; i++) @@ -426,12 +426,12 @@ std::tuple write_index_array_data_to_buffer_untouched(gsl::span write_index_array_data_to_buffer_untouched(gsl::span dst, const std::vector > &first_count_arguments) { - u32 address = rsx::get_address(rsx::method_registers[NV4097_SET_INDEX_ARRAY_ADDRESS], rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf); - rsx::index_array_type type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4); + u32 address = rsx::get_address(rsx::method_registers.index_array_address(), rsx::method_registers.index_array_location()); + rsx::index_array_type type = rsx::method_registers.index_type(); u32 type_size = gsl::narrow(get_index_type_size(type)); - bool is_primitive_restart_enabled = !!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE]; - u16 primitive_restart_index = rsx::method_registers[NV4097_SET_RESTART_INDEX]; + bool is_primitive_restart_enabled = rsx::method_registers.restart_index_enabled(); + u16 primitive_restart_index = rsx::method_registers.restart_index(); // Disjoint first_counts ranges not supported atm for (int i = 0; i < first_count_arguments.size() - 1; i++) diff --git a/rpcs3/Emu/RSX/Common/surface_store.h b/rpcs3/Emu/RSX/Common/surface_store.h index 4fd86dd9da..3c14764aa8 100644 --- a/rpcs3/Emu/RSX/Common/surface_store.h +++ b/rpcs3/Emu/RSX/Common/surface_store.h @@ -141,19 +141,16 @@ namespace rsx template void prepare_render_target( command_list_type command_list, - u32 set_surface_format_reg, + surface_color_format color_format, surface_depth_format depth_format, u32 clip_horizontal_reg, u32 clip_vertical_reg, surface_target set_surface_target, const std::array &surface_addresses, u32 address_z, Args&&... extra_params) { - u32 clip_width = clip_horizontal_reg >> 16; - u32 clip_height = clip_vertical_reg >> 16; - u32 clip_x = clip_horizontal_reg; - u32 clip_y = clip_vertical_reg; - - surface_color_format color_format = to_surface_color_format(set_surface_format_reg & 0x1f); - surface_depth_format depth_format = to_surface_depth_format((set_surface_format_reg >> 5) & 0x7); + u32 clip_width = clip_horizontal_reg; + u32 clip_height = clip_vertical_reg; +// u32 clip_x = clip_horizontal_reg; +// u32 clip_y = clip_vertical_reg; // Make previous RTTs sampleable for (std::tuple &rtt : m_bound_render_targets) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index fdaf42161f..4e44fd18f4 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -77,8 +77,8 @@ std::vector D3D12GSRender::upload_vertex_attrib u32 vertex_count = get_vertex_count(vertex_ranges); size_t offset_in_vertex_buffers_buffer = 0; - u32 input_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK]; - EXPECTS(rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_INDEX] == 0); + u32 input_mask = rsx::method_registers.vertex_attrib_input_mask(); + EXPECTS(rsx::method_registers.vertex_data_base_index() == 0); for (int index = 0; index < rsx::limits::vertex_count; ++index) { @@ -86,17 +86,17 @@ std::vector D3D12GSRender::upload_vertex_attrib if (!enabled) continue; - if (vertex_arrays_info[index].size > 0) + if (rsx::method_registers.vertex_arrays_info[index].size > 0) { // Active vertex array - const rsx::data_array_format_info &info = vertex_arrays_info[index]; + const rsx::data_array_format_info &info = rsx::method_registers.vertex_arrays_info[index]; u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size); UINT buffer_size = element_size * vertex_count; size_t heap_offset = m_buffer_data.alloc(buffer_size); - u32 base_offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET]; - u32 offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + index]; + u32 base_offset = rsx::method_registers.vertex_data_base_offset(); + u32 offset = rsx::method_registers.vertex_arrays_info[index].offset(); u32 address = base_offset + rsx::get_address(offset & 0x7fffffff, offset >> 31); const gsl::byte *src_ptr = gsl::narrow_cast(vm::base(address)); @@ -117,11 +117,11 @@ std::vector D3D12GSRender::upload_vertex_attrib m_timers.buffer_upload_size += buffer_size; } - else if (register_vertex_info[index].size > 0) + else if (rsx::method_registers.register_vertex_info[index].size > 0) { // In register vertex attribute - const rsx::data_array_format_info &info = register_vertex_info[index]; - const std::vector &data = register_vertex_data[index]; + const rsx::data_array_format_info &info = rsx::method_registers.register_vertex_info[index]; + const std::vector &data = rsx::method_registers.register_vertex_data[index]; u32 element_size = rsx::get_vertex_type_size_on_host(info.type, info.size); UINT buffer_size = gsl::narrow(data.size()); @@ -224,13 +224,15 @@ void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex) // Separate constant buffer void *mapped_buffer = m_buffer_data.map(CD3DX12_RANGE(heap_offset, heap_offset + 256)); fill_scale_offset_data(mapped_buffer); - int is_alpha_tested = !!(rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE]); - u8 alpha_ref_raw = (u8)(rsx::method_registers[NV4097_SET_ALPHA_REF] & 0xFF); + int is_alpha_tested = rsx::method_registers.alpha_test_enabled(); + u8 alpha_ref_raw = rsx::method_registers.alpha_ref(); float alpha_ref = alpha_ref_raw / 255.f; memcpy((char*)mapped_buffer + 16 * sizeof(float), &is_alpha_tested, sizeof(int)); memcpy((char*)mapped_buffer + 17 * sizeof(float), &alpha_ref, sizeof(float)); - memcpy((char*)mapped_buffer + 18 * sizeof(float), &rsx::method_registers[NV4097_SET_FOG_PARAMS], sizeof(float)); - memcpy((char*)mapped_buffer + 19 * sizeof(float), &rsx::method_registers[NV4097_SET_FOG_PARAMS + 1], sizeof(float)); + f32 fogp0 = rsx::method_registers.fog_params_0(); + f32 fogp1 = rsx::method_registers.fog_params_1(); + memcpy((char*)mapped_buffer + 18 * sizeof(float), &fogp0, sizeof(float)); + memcpy((char*)mapped_buffer + 19 * sizeof(float), &fogp1, sizeof(float)); m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + 256)); @@ -321,7 +323,7 @@ std::tuple> D3D12GSRe size_t vertex_count; std::vector vertex_buffer_view; std::tie(vertex_buffer_view, vertex_count) = upload_inlined_vertex_array( - vertex_arrays_info, + rsx::method_registers.vertex_arrays_info, { (const gsl::byte*) inline_vertex_array.data(), gsl::narrow(inline_vertex_array.size() * sizeof(uint)) }, m_buffer_data, m_vertex_buffer_data.Get(), command_list); @@ -355,7 +357,7 @@ std::tuple> D3D12GSRe // Index count size_t index_count = get_index_count(draw_mode, gsl::narrow(get_vertex_count(first_count_commands))); - rsx::index_array_type indexed_type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4); + rsx::index_array_type indexed_type = rsx::method_registers.index_type(); size_t index_size = get_index_type_size(indexed_type); // Alloc diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp index 2e37cfae94..518d79a15f 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp @@ -6,79 +6,79 @@ #include "Emu/RSX/GCM.h" -D3D12_BLEND_OP get_blend_op(u16 op) +D3D12_BLEND_OP get_blend_op(rsx::blend_equation op) { switch (op) { - case CELL_GCM_FUNC_ADD: return D3D12_BLEND_OP_ADD; - case CELL_GCM_FUNC_SUBTRACT: return D3D12_BLEND_OP_SUBTRACT; - case CELL_GCM_FUNC_REVERSE_SUBTRACT: return D3D12_BLEND_OP_REV_SUBTRACT; - case CELL_GCM_MIN: return D3D12_BLEND_OP_MIN; - case CELL_GCM_MAX: return D3D12_BLEND_OP_MAX; - case CELL_GCM_FUNC_ADD_SIGNED: - case CELL_GCM_FUNC_REVERSE_ADD_SIGNED: - case CELL_GCM_FUNC_REVERSE_SUBTRACT_SIGNED: + case rsx::blend_equation::add: return D3D12_BLEND_OP_ADD; + case rsx::blend_equation::substract: return D3D12_BLEND_OP_SUBTRACT; + case rsx::blend_equation::reverse_substract: return D3D12_BLEND_OP_REV_SUBTRACT; + case rsx::blend_equation::min: return D3D12_BLEND_OP_MIN; + case rsx::blend_equation::max: return D3D12_BLEND_OP_MAX; + case rsx::blend_equation::add_signed: + case rsx::blend_equation::reverse_add_signed: + case rsx::blend_equation::reverse_substract_signed: break; } throw EXCEPTION("Invalid or unsupported blend op (0x%x)", op); } -D3D12_BLEND get_blend_factor(u16 factor) +D3D12_BLEND get_blend_factor(rsx::blend_factor factor) { switch (factor) { - case CELL_GCM_ZERO: return D3D12_BLEND_ZERO; - case CELL_GCM_ONE: return D3D12_BLEND_ONE; - case CELL_GCM_SRC_COLOR: return D3D12_BLEND_SRC_COLOR; - case CELL_GCM_ONE_MINUS_SRC_COLOR: return D3D12_BLEND_INV_SRC_COLOR; - case CELL_GCM_SRC_ALPHA: return D3D12_BLEND_SRC_ALPHA; - case CELL_GCM_ONE_MINUS_SRC_ALPHA: return D3D12_BLEND_INV_SRC_ALPHA; - case CELL_GCM_DST_ALPHA: return D3D12_BLEND_DEST_ALPHA; - case CELL_GCM_ONE_MINUS_DST_ALPHA: return D3D12_BLEND_INV_DEST_ALPHA; - case CELL_GCM_DST_COLOR: return D3D12_BLEND_DEST_COLOR; - case CELL_GCM_ONE_MINUS_DST_COLOR: return D3D12_BLEND_INV_DEST_COLOR; - case CELL_GCM_SRC_ALPHA_SATURATE: return D3D12_BLEND_SRC_ALPHA_SAT; - case CELL_GCM_CONSTANT_COLOR: - case CELL_GCM_CONSTANT_ALPHA: + case rsx::blend_factor::zero: return D3D12_BLEND_ZERO; + case rsx::blend_factor::one: return D3D12_BLEND_ONE; + case rsx::blend_factor::src_color: return D3D12_BLEND_SRC_COLOR; + case rsx::blend_factor::one_minus_src_color: return D3D12_BLEND_INV_SRC_COLOR; + case rsx::blend_factor::src_alpha: return D3D12_BLEND_SRC_ALPHA; + case rsx::blend_factor::one_minus_src_alpha: return D3D12_BLEND_INV_SRC_ALPHA; + case rsx::blend_factor::dst_alpha: return D3D12_BLEND_DEST_ALPHA; + case rsx::blend_factor::one_minus_dst_alpha: return D3D12_BLEND_INV_DEST_ALPHA; + case rsx::blend_factor::dst_color: return D3D12_BLEND_DEST_COLOR; + case rsx::blend_factor::one_minus_dst_color: return D3D12_BLEND_INV_DEST_COLOR; + case rsx::blend_factor::src_alpha_saturate: return D3D12_BLEND_SRC_ALPHA_SAT; + case rsx::blend_factor::constant_color: + case rsx::blend_factor::constant_alpha: { - LOG_ERROR(RSX,"Constant blend factor not supported. Using ONE instead"); + LOG_ERROR(RSX, "Constant blend factor not supported. Using ONE instead"); return D3D12_BLEND_ONE; } - case CELL_GCM_ONE_MINUS_CONSTANT_COLOR: - case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA: + case rsx::blend_factor::one_minus_constant_color: + case rsx::blend_factor::one_minus_constant_alpha: { - LOG_ERROR(RSX,"Inv Constant blend factor not supported. Using ZERO instead"); + LOG_ERROR(RSX, "Inv Constant blend factor not supported. Using ZERO instead"); return D3D12_BLEND_ZERO; } } throw EXCEPTION("Invalid blend factor (0x%x)", factor); } -D3D12_BLEND get_blend_factor_alpha(u16 factor) +D3D12_BLEND get_blend_factor_alpha(rsx::blend_factor factor) { switch (factor) { - case CELL_GCM_ZERO: return D3D12_BLEND_ZERO; - case CELL_GCM_ONE: return D3D12_BLEND_ONE; - case CELL_GCM_SRC_COLOR: return D3D12_BLEND_SRC_ALPHA; - case CELL_GCM_ONE_MINUS_SRC_COLOR: return D3D12_BLEND_INV_SRC_ALPHA; - case CELL_GCM_SRC_ALPHA: return D3D12_BLEND_SRC_ALPHA; - case CELL_GCM_ONE_MINUS_SRC_ALPHA: return D3D12_BLEND_INV_SRC_ALPHA; - case CELL_GCM_DST_ALPHA: return D3D12_BLEND_DEST_ALPHA; - case CELL_GCM_ONE_MINUS_DST_ALPHA: return D3D12_BLEND_INV_DEST_ALPHA; - case CELL_GCM_DST_COLOR: return D3D12_BLEND_DEST_ALPHA; - case CELL_GCM_ONE_MINUS_DST_COLOR: return D3D12_BLEND_INV_DEST_ALPHA; - case CELL_GCM_SRC_ALPHA_SATURATE: return D3D12_BLEND_SRC_ALPHA_SAT; - case CELL_GCM_CONSTANT_COLOR: - case CELL_GCM_CONSTANT_ALPHA: + case rsx::blend_factor::zero: return D3D12_BLEND_ZERO; + case rsx::blend_factor::one: return D3D12_BLEND_ONE; + case rsx::blend_factor::src_color: return D3D12_BLEND_SRC_ALPHA; + case rsx::blend_factor::one_minus_src_color: return D3D12_BLEND_INV_SRC_ALPHA; + case rsx::blend_factor::src_alpha: return D3D12_BLEND_SRC_ALPHA; + case rsx::blend_factor::one_minus_src_alpha: return D3D12_BLEND_INV_SRC_ALPHA; + case rsx::blend_factor::dst_alpha: return D3D12_BLEND_DEST_ALPHA; + case rsx::blend_factor::one_minus_dst_alpha: return D3D12_BLEND_INV_DEST_ALPHA; + case rsx::blend_factor::dst_color: return D3D12_BLEND_DEST_ALPHA; + case rsx::blend_factor::one_minus_dst_color: return D3D12_BLEND_INV_DEST_ALPHA; + case rsx::blend_factor::src_alpha_saturate: return D3D12_BLEND_SRC_ALPHA_SAT; + case rsx::blend_factor::constant_color: + case rsx::blend_factor::constant_alpha: { - LOG_ERROR(RSX,"Constant blend factor not supported. Using ONE instead"); + LOG_ERROR(RSX, "Constant blend factor not supported. Using ONE instead"); return D3D12_BLEND_ONE; } - case CELL_GCM_ONE_MINUS_CONSTANT_COLOR: - case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA: + case rsx::blend_factor::one_minus_constant_color: + case rsx::blend_factor::one_minus_constant_alpha: { - LOG_ERROR(RSX,"Inv Constant blend factor not supported. Using ZERO instead"); + LOG_ERROR(RSX, "Inv Constant blend factor not supported. Using ZERO instead"); return D3D12_BLEND_ZERO; } } @@ -88,25 +88,25 @@ D3D12_BLEND get_blend_factor_alpha(u16 factor) /** * Convert GCM logic op code to D3D12 one */ -D3D12_LOGIC_OP get_logic_op(u32 op) +D3D12_LOGIC_OP get_logic_op(rsx::logic_op op) { switch (op) { - case CELL_GCM_CLEAR: return D3D12_LOGIC_OP_CLEAR; - case CELL_GCM_AND: return D3D12_LOGIC_OP_AND; - case CELL_GCM_AND_REVERSE: return D3D12_LOGIC_OP_AND_REVERSE; - case CELL_GCM_COPY: return D3D12_LOGIC_OP_COPY; - case CELL_GCM_AND_INVERTED: return D3D12_LOGIC_OP_AND_INVERTED; - case CELL_GCM_NOOP: return D3D12_LOGIC_OP_NOOP; - case CELL_GCM_XOR: return D3D12_LOGIC_OP_XOR; - case CELL_GCM_OR: return D3D12_LOGIC_OP_OR; - case CELL_GCM_NOR: return D3D12_LOGIC_OP_NOR; - case CELL_GCM_EQUIV: return D3D12_LOGIC_OP_EQUIV; - case CELL_GCM_INVERT: return D3D12_LOGIC_OP_INVERT; - case CELL_GCM_OR_REVERSE: return D3D12_LOGIC_OP_OR_REVERSE; - case CELL_GCM_COPY_INVERTED: return D3D12_LOGIC_OP_COPY_INVERTED; - case CELL_GCM_OR_INVERTED: return D3D12_LOGIC_OP_OR_INVERTED; - case CELL_GCM_NAND: return D3D12_LOGIC_OP_NAND; + case rsx::logic_op::logic_clear: return D3D12_LOGIC_OP_CLEAR; + case rsx::logic_op::logic_and: return D3D12_LOGIC_OP_AND; + case rsx::logic_op::logic_and_reverse: return D3D12_LOGIC_OP_AND_REVERSE; + case rsx::logic_op::logic_copy: return D3D12_LOGIC_OP_COPY; + case rsx::logic_op::logic_and_inverted: return D3D12_LOGIC_OP_AND_INVERTED; + case rsx::logic_op::logic_noop: return D3D12_LOGIC_OP_NOOP; + case rsx::logic_op::logic_xor: return D3D12_LOGIC_OP_XOR; + case rsx::logic_op::logic_or: return D3D12_LOGIC_OP_OR; + case rsx::logic_op::logic_nor: return D3D12_LOGIC_OP_NOR; + case rsx::logic_op::logic_equiv: return D3D12_LOGIC_OP_EQUIV; + case rsx::logic_op::logic_invert: return D3D12_LOGIC_OP_INVERT; + case rsx::logic_op::logic_or_reverse: return D3D12_LOGIC_OP_OR_REVERSE; + case rsx::logic_op::logic_copy_inverted: return D3D12_LOGIC_OP_COPY_INVERTED; + case rsx::logic_op::logic_or_inverted: return D3D12_LOGIC_OP_OR_INVERTED; + case rsx::logic_op::logic_nand: return D3D12_LOGIC_OP_NAND; } throw EXCEPTION("Invalid logic op (0x%x)", op); } @@ -114,34 +114,34 @@ D3D12_LOGIC_OP get_logic_op(u32 op) /** * Convert GCM stencil op code to D3D12 one */ -D3D12_STENCIL_OP get_stencil_op(u32 op) +D3D12_STENCIL_OP get_stencil_op(rsx::stencil_op op) { switch (op) { - case CELL_GCM_KEEP: return D3D12_STENCIL_OP_KEEP; - case CELL_GCM_ZERO: return D3D12_STENCIL_OP_ZERO; - case CELL_GCM_REPLACE: return D3D12_STENCIL_OP_REPLACE; - case CELL_GCM_INCR: return D3D12_STENCIL_OP_INCR_SAT; - case CELL_GCM_DECR: return D3D12_STENCIL_OP_DECR_SAT; - case CELL_GCM_INVERT: return D3D12_STENCIL_OP_INVERT; - case CELL_GCM_INCR_WRAP: return D3D12_STENCIL_OP_INCR; - case CELL_GCM_DECR_WRAP: return D3D12_STENCIL_OP_DECR; + case rsx::stencil_op::keep: return D3D12_STENCIL_OP_KEEP; + case rsx::stencil_op::zero: return D3D12_STENCIL_OP_ZERO; + case rsx::stencil_op::replace: return D3D12_STENCIL_OP_REPLACE; + case rsx::stencil_op::incr: return D3D12_STENCIL_OP_INCR_SAT; + case rsx::stencil_op::decr: return D3D12_STENCIL_OP_DECR_SAT; + case rsx::stencil_op::invert: return D3D12_STENCIL_OP_INVERT; + case rsx::stencil_op::incr_wrap: return D3D12_STENCIL_OP_INCR; + case rsx::stencil_op::decr_wrap: return D3D12_STENCIL_OP_DECR; } throw EXCEPTION("Invalid stencil op (0x%x)", op); } -D3D12_COMPARISON_FUNC get_compare_func(u32 op) +D3D12_COMPARISON_FUNC get_compare_func(rsx::comparaison_function op) { switch (op) { - case CELL_GCM_NEVER: return D3D12_COMPARISON_FUNC_NEVER; - case CELL_GCM_LESS: return D3D12_COMPARISON_FUNC_LESS; - case CELL_GCM_EQUAL: return D3D12_COMPARISON_FUNC_EQUAL; - case CELL_GCM_LEQUAL: return D3D12_COMPARISON_FUNC_LESS_EQUAL; - case CELL_GCM_GREATER: return D3D12_COMPARISON_FUNC_GREATER; - case CELL_GCM_NOTEQUAL: return D3D12_COMPARISON_FUNC_NOT_EQUAL; - case CELL_GCM_GEQUAL: return D3D12_COMPARISON_FUNC_GREATER_EQUAL; - case CELL_GCM_ALWAYS: return D3D12_COMPARISON_FUNC_ALWAYS; + case rsx::comparaison_function::never: return D3D12_COMPARISON_FUNC_NEVER; + case rsx::comparaison_function::less: return D3D12_COMPARISON_FUNC_LESS; + case rsx::comparaison_function::equal: return D3D12_COMPARISON_FUNC_EQUAL; + case rsx::comparaison_function::less_or_equal: return D3D12_COMPARISON_FUNC_LESS_EQUAL; + case rsx::comparaison_function::greater: return D3D12_COMPARISON_FUNC_GREATER; + case rsx::comparaison_function::not_equal: return D3D12_COMPARISON_FUNC_NOT_EQUAL; + case rsx::comparaison_function::greater_or_equal: return D3D12_COMPARISON_FUNC_GREATER_EQUAL; + case rsx::comparaison_function::always: return D3D12_COMPARISON_FUNC_ALWAYS; } throw EXCEPTION("Invalid or unsupported compare func (0x%x)", op); } @@ -371,24 +371,23 @@ DXGI_FORMAT get_depth_samplable_surface_format(rsx::surface_depth_format format) throw EXCEPTION("Invalid format (0x%x)", format); } -BOOL get_front_face_ccw(u32 ffv) +BOOL get_front_face_ccw(rsx::front_face ffv) { switch (ffv) { - default: // Disgaea 3 pass some garbage value at startup, this is needed to survive. - case CELL_GCM_CW: return FALSE; - case CELL_GCM_CCW: return TRUE; + case rsx::front_face::cw: return FALSE; + case rsx::front_face::ccw: return TRUE; } throw EXCEPTION("Invalid front face value (0x%x)", ffv); } -D3D12_CULL_MODE get_cull_face(u32 cfv) +D3D12_CULL_MODE get_cull_face(rsx::cull_face cfv) { switch (cfv) { - case CELL_GCM_FRONT: return D3D12_CULL_MODE_FRONT; - case CELL_GCM_BACK: return D3D12_CULL_MODE_BACK; - default: return D3D12_CULL_MODE_NONE; + case rsx::cull_face::front: return D3D12_CULL_MODE_FRONT; + case rsx::cull_face::back: return D3D12_CULL_MODE_BACK; + case rsx::cull_face::front_and_back: return D3D12_CULL_MODE_NONE; } throw EXCEPTION("Invalid cull face value (0x%x)", cfv); } @@ -489,13 +488,13 @@ DXGI_FORMAT get_vertex_attribute_format(rsx::vertex_base_type type, u8 size) throw EXCEPTION("Invalid or unsupported type or size (type=0x%x, size=0x%x)", type, size); } -D3D12_RECT get_scissor(u32 horizontal, u32 vertical) +D3D12_RECT get_scissor(u16 clip_origin_x, u16 clip_origin_y, u16 clip_w, u16 clip_h) { return{ - horizontal & 0xFFFF, - vertical & 0xFFFF, - (horizontal & 0xFFFF) + (horizontal >> 16), - (vertical & 0xFFFF) + (vertical >> 16) + clip_origin_x, + clip_origin_y, + clip_w, + clip_h, }; } #endif diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.h b/rpcs3/Emu/RSX/D3D12/D3D12Formats.h index 677986e5a6..4f0159ef08 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.h @@ -5,32 +5,32 @@ /** * Convert GCM blend operator code to D3D12 one */ -D3D12_BLEND_OP get_blend_op(u16 op); +D3D12_BLEND_OP get_blend_op(rsx::blend_equation op); /** * Convert GCM blend factor code to D3D12 one */ -D3D12_BLEND get_blend_factor(u16 factor); +D3D12_BLEND get_blend_factor(rsx::blend_factor factor); /** * Convert GCM blend factor code to D3D12 one for alpha component */ -D3D12_BLEND get_blend_factor_alpha(u16 factor); +D3D12_BLEND get_blend_factor_alpha(rsx::blend_factor factor); /** * Convert GCM logic op code to D3D12 one */ -D3D12_LOGIC_OP get_logic_op(u32 op); +D3D12_LOGIC_OP get_logic_op(rsx::logic_op op); /** * Convert GCM stencil op code to D3D12 one */ -D3D12_STENCIL_OP get_stencil_op(u32 op); +D3D12_STENCIL_OP get_stencil_op(rsx::stencil_op op); /** * Convert GCM comparison function code to D3D12 one. */ -D3D12_COMPARISON_FUNC get_compare_func(u32 op); +D3D12_COMPARISON_FUNC get_compare_func(rsx::comparaison_function op); /** * Convert GCM texture format to an equivalent one supported by D3D12. @@ -91,12 +91,12 @@ DXGI_FORMAT get_depth_samplable_surface_format(rsx::surface_depth_format format) /** * Convert front face value to bool value telling wheter front face is counterclockwise or not */ -BOOL get_front_face_ccw(u32 set_front_face_value); +BOOL get_front_face_ccw(rsx::front_face set_front_face_value); /** * Convert cull face value to a D3D12_CULL_MODE telling wheter cull face is front or back */ -D3D12_CULL_MODE get_cull_face(u32 set_cull_face_value); +D3D12_CULL_MODE get_cull_face(rsx::cull_face set_cull_face_value); /** * Convert index type to DXGI_FORMAT @@ -111,4 +111,4 @@ DXGI_FORMAT get_vertex_attribute_format(rsx::vertex_base_type type, u8 size); /** * Convert scissor register value to D3D12_RECT */ -D3D12_RECT get_scissor(u32 horizontal, u32 vertical); +D3D12_RECT get_scissor(u16 clip_origin_x, u16 clip_origin_y, u16 clip_w, u16 clip_h); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp index 47bc395ad5..8f1580b860 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp @@ -329,7 +329,7 @@ void D3D12GSRender::end() m_timers.program_load_duration += std::chrono::duration_cast(program_load_end - program_load_start).count(); get_current_resource_storage().command_list->SetGraphicsRootSignature(m_shared_root_signature.Get()); - get_current_resource_storage().command_list->OMSetStencilRef(rsx::method_registers[NV4097_SET_STENCIL_FUNC_REF]); + get_current_resource_storage().command_list->OMSetStencilRef(rsx::method_registers.stencil_func_ref()); std::chrono::time_point constants_duration_start = std::chrono::system_clock::now(); @@ -425,8 +425,8 @@ void D3D12GSRender::end() m_timers.texture_duration += std::chrono::duration_cast(texture_duration_end - texture_duration_start).count(); set_rtt_and_ds(get_current_resource_storage().command_list.Get()); - int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; - int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; + int clip_w = rsx::method_registers.surface_clip_width(); + int clip_h = rsx::method_registers.surface_clip_height(); D3D12_VIEWPORT viewport = { @@ -434,12 +434,13 @@ void D3D12GSRender::end() 0.f, (float)clip_w, (float)clip_h, - (f32&)rsx::method_registers[NV4097_SET_CLIP_MIN], - (f32&)rsx::method_registers[NV4097_SET_CLIP_MAX] + rsx::method_registers.clip_min(), + rsx::method_registers.clip_max(), }; get_current_resource_storage().command_list->RSSetViewports(1, &viewport); - get_current_resource_storage().command_list->RSSetScissorRects(1, &get_scissor(rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL], rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL])); + get_current_resource_storage().command_list->RSSetScissorRects(1, &get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(), + rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height())); get_current_resource_storage().command_list->IASetPrimitiveTopology(get_primitive_topology(draw_mode)); @@ -485,7 +486,7 @@ void D3D12GSRender::flip(int buffer) ID3D12Resource *resource_to_flip; float viewport_w, viewport_h; - if (!is_flip_surface_in_global_memory(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))) + if (!is_flip_surface_in_global_memory(rsx::method_registers.surface_color_target())) { resource_storage &storage = get_current_resource_storage(); VERIFY(storage.ram_framebuffer == nullptr); @@ -577,7 +578,7 @@ void D3D12GSRender::flip(int buffer) shader_resource_view_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; shader_resource_view_desc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D; shader_resource_view_desc.Texture2D.MipLevels = 1; - if (is_flip_surface_in_global_memory(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))) + if (is_flip_surface_in_global_memory(rsx::method_registers.surface_color_target())) shader_resource_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; else shader_resource_view_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( @@ -622,7 +623,7 @@ void D3D12GSRender::flip(int buffer) if (!g_cfg_rsx_overlay) get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_backbuffer[m_swap_chain->GetCurrentBackBufferIndex()].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); - if (is_flip_surface_in_global_memory(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) && resource_to_flip != nullptr) + if (is_flip_surface_in_global_memory(rsx::method_registers.surface_color_target()) && resource_to_flip != nullptr) get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(resource_to_flip, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_RENDER_TARGET)); CHECK_HRESULT(get_current_resource_storage().command_list->Close()); m_command_queue->ExecuteCommandLists(1, (ID3D12CommandList**)get_current_resource_storage().command_list.GetAddressOf()); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h index ef5e34ce3f..feae94fe70 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12GSRender.h @@ -61,8 +61,6 @@ private: data_cache m_texture_cache; bool invalidate_address(u32 addr); - rsx::surface_info m_surface; - RSXVertexProgram m_vertex_program; RSXFragmentProgram m_fragment_program; PipelineStateObjectCache m_pso_cache; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp index e844e4a765..5e9787c183 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp @@ -60,72 +60,72 @@ void D3D12GSRender::load_program() }; prop.Blend = CD3D12_BLEND_DESC; - if (rsx::method_registers[NV4097_SET_BLEND_ENABLE]) + if (rsx::method_registers.blend_enabled()) { prop.Blend.RenderTarget[0].BlendEnable = true; - if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x2) + if (rsx::method_registers.blend_enabled_surface_1()) prop.Blend.RenderTarget[1].BlendEnable = true; - if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x4) + if (rsx::method_registers.blend_enabled_surface_2()) prop.Blend.RenderTarget[2].BlendEnable = true; - if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x8) + if (rsx::method_registers.blend_enabled_surface_3()) prop.Blend.RenderTarget[3].BlendEnable = true; - prop.Blend.RenderTarget[0].BlendOp = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] & 0xFFFF); - prop.Blend.RenderTarget[0].BlendOpAlpha = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] >> 16); + prop.Blend.RenderTarget[0].BlendOp = get_blend_op(rsx::method_registers.blend_equation_rgb()); + prop.Blend.RenderTarget[0].BlendOpAlpha = get_blend_op(rsx::method_registers.blend_equation_a()); - if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x2) + if (rsx::method_registers.blend_enabled_surface_1()) { - prop.Blend.RenderTarget[1].BlendOp = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] & 0xFFFF); - prop.Blend.RenderTarget[1].BlendOpAlpha = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] >> 16); + prop.Blend.RenderTarget[1].BlendOp = get_blend_op(rsx::method_registers.blend_equation_rgb()); + prop.Blend.RenderTarget[1].BlendOpAlpha = get_blend_op(rsx::method_registers.blend_equation_a()); } - if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x4) + if (rsx::method_registers.blend_enabled_surface_2()) { - prop.Blend.RenderTarget[2].BlendOp = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] & 0xFFFF); - prop.Blend.RenderTarget[2].BlendOpAlpha = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] >> 16); + prop.Blend.RenderTarget[2].BlendOp = get_blend_op(rsx::method_registers.blend_equation_rgb()); + prop.Blend.RenderTarget[2].BlendOpAlpha = get_blend_op(rsx::method_registers.blend_equation_a()); } - if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x8) + if (rsx::method_registers.blend_enabled_surface_3()) { - prop.Blend.RenderTarget[3].BlendOp = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] & 0xFFFF); - prop.Blend.RenderTarget[3].BlendOpAlpha = get_blend_op(rsx::method_registers[NV4097_SET_BLEND_EQUATION] >> 16); + prop.Blend.RenderTarget[3].BlendOp = get_blend_op(rsx::method_registers.blend_equation_rgb()); + prop.Blend.RenderTarget[3].BlendOpAlpha = get_blend_op(rsx::method_registers.blend_equation_a()); } - prop.Blend.RenderTarget[0].SrcBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[0].DestBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[0].SrcBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] >> 16); - prop.Blend.RenderTarget[0].DestBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] >> 16); + prop.Blend.RenderTarget[0].SrcBlend = get_blend_factor(rsx::method_registers.blend_func_sfactor_rgb()); + prop.Blend.RenderTarget[0].DestBlend = get_blend_factor(rsx::method_registers.blend_func_dfactor_rgb()); + prop.Blend.RenderTarget[0].SrcBlendAlpha = get_blend_factor_alpha(rsx::method_registers.blend_func_sfactor_a()); + prop.Blend.RenderTarget[0].DestBlendAlpha = get_blend_factor_alpha(rsx::method_registers.blend_func_dfactor_a()); - if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x2) + if (rsx::method_registers.blend_enabled_surface_1()) { - prop.Blend.RenderTarget[1].SrcBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[1].DestBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[1].SrcBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] >> 16); - prop.Blend.RenderTarget[1].DestBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] >> 16); + prop.Blend.RenderTarget[1].SrcBlend = get_blend_factor(rsx::method_registers.blend_func_sfactor_rgb()); + prop.Blend.RenderTarget[1].DestBlend = get_blend_factor(rsx::method_registers.blend_func_dfactor_rgb()); + prop.Blend.RenderTarget[1].SrcBlendAlpha = get_blend_factor_alpha(rsx::method_registers.blend_func_sfactor_a()); + prop.Blend.RenderTarget[1].DestBlendAlpha = get_blend_factor_alpha(rsx::method_registers.blend_func_dfactor_a()); } - if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x4) + if (rsx::method_registers.blend_enabled_surface_2()) { - prop.Blend.RenderTarget[2].SrcBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[2].DestBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[2].SrcBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] >> 16); - prop.Blend.RenderTarget[2].DestBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] >> 16); + prop.Blend.RenderTarget[2].SrcBlend = get_blend_factor(rsx::method_registers.blend_func_sfactor_rgb()); + prop.Blend.RenderTarget[2].DestBlend = get_blend_factor(rsx::method_registers.blend_func_dfactor_rgb()); + prop.Blend.RenderTarget[2].SrcBlendAlpha = get_blend_factor_alpha(rsx::method_registers.blend_func_sfactor_a()); + prop.Blend.RenderTarget[2].DestBlendAlpha = get_blend_factor_alpha(rsx::method_registers.blend_func_dfactor_a()); } - if (rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT] & 0x8) + if (rsx::method_registers.blend_enabled_surface_3()) { - prop.Blend.RenderTarget[3].SrcBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[3].DestBlend = get_blend_factor(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] & 0xFFFF); - prop.Blend.RenderTarget[3].SrcBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] >> 16); - prop.Blend.RenderTarget[3].DestBlendAlpha = get_blend_factor_alpha(rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] >> 16); + prop.Blend.RenderTarget[3].SrcBlend = get_blend_factor(rsx::method_registers.blend_func_sfactor_rgb()); + prop.Blend.RenderTarget[3].DestBlend = get_blend_factor(rsx::method_registers.blend_func_dfactor_rgb()); + prop.Blend.RenderTarget[3].SrcBlendAlpha = get_blend_factor_alpha(rsx::method_registers.blend_func_sfactor_a()); + prop.Blend.RenderTarget[3].DestBlendAlpha = get_blend_factor_alpha(rsx::method_registers.blend_func_dfactor_a()); } } - if (rsx::method_registers[NV4097_SET_LOGIC_OP_ENABLE]) + if (rsx::method_registers.logic_op_enabled()) { prop.Blend.RenderTarget[0].LogicOpEnable = true; - prop.Blend.RenderTarget[0].LogicOp = get_logic_op(rsx::method_registers[NV4097_SET_LOGIC_OP]); + prop.Blend.RenderTarget[0].LogicOp = get_logic_op(rsx::method_registers.logic_operation()); } // if (m_set_blend_color) @@ -133,10 +133,10 @@ void D3D12GSRender::load_program() // glBlendColor(m_blend_color_r, m_blend_color_g, m_blend_color_b, m_blend_color_a); // checkForGlError("glBlendColor"); } - prop.DepthStencilFormat = get_depth_stencil_surface_format(m_surface.depth_format); - prop.RenderTargetsFormat = get_color_surface_format(m_surface.color_format); + prop.DepthStencilFormat = get_depth_stencil_surface_format(rsx::method_registers.surface_depth_fmt()); + prop.RenderTargetsFormat = get_color_surface_format(rsx::method_registers.surface_color()); - switch (rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) + switch (rsx::method_registers.surface_color_target()) { case rsx::surface_target::surface_a: case rsx::surface_target::surface_b: @@ -154,36 +154,36 @@ void D3D12GSRender::load_program() default: break; } - if (!!(rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE])) + if (rsx::method_registers.depth_test_enabled()) { prop.DepthStencil.DepthEnable = TRUE; - prop.DepthStencil.DepthFunc = get_compare_func(rsx::method_registers[NV4097_SET_DEPTH_FUNC]); + prop.DepthStencil.DepthFunc = get_compare_func(rsx::method_registers.depth_func()); } else prop.DepthStencil.DepthEnable = FALSE; - prop.DepthStencil.DepthWriteMask = !!(rsx::method_registers[NV4097_SET_DEPTH_MASK]) ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; - prop.DepthStencil.StencilEnable = !!(rsx::method_registers[NV4097_SET_STENCIL_TEST_ENABLE]); - prop.DepthStencil.StencilReadMask = rsx::method_registers[NV4097_SET_STENCIL_FUNC_MASK]; - prop.DepthStencil.StencilWriteMask = rsx::method_registers[NV4097_SET_STENCIL_MASK]; - prop.DepthStencil.FrontFace.StencilPassOp = get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_ZPASS]); - prop.DepthStencil.FrontFace.StencilDepthFailOp = get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_ZFAIL]); - prop.DepthStencil.FrontFace.StencilFailOp = get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_FAIL]); - prop.DepthStencil.FrontFace.StencilFunc = get_compare_func(rsx::method_registers[NV4097_SET_STENCIL_FUNC]); + prop.DepthStencil.DepthWriteMask = rsx::method_registers.depth_write_enabled() ? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO; + prop.DepthStencil.StencilEnable = rsx::method_registers.stencil_test_enabled(); + prop.DepthStencil.StencilReadMask = rsx::method_registers.stencil_func_mask(); + prop.DepthStencil.StencilWriteMask = rsx::method_registers.stencil_mask(); + prop.DepthStencil.FrontFace.StencilPassOp = get_stencil_op(rsx::method_registers.stencil_op_zpass()); + prop.DepthStencil.FrontFace.StencilDepthFailOp = get_stencil_op(rsx::method_registers.stencil_op_zfail()); + prop.DepthStencil.FrontFace.StencilFailOp = get_stencil_op(rsx::method_registers.stencil_op_fail()); + prop.DepthStencil.FrontFace.StencilFunc = get_compare_func(rsx::method_registers.stencil_func()); - if (rsx::method_registers[NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE]) + if (rsx::method_registers.two_sided_stencil_test_enabled()) { - prop.DepthStencil.BackFace.StencilFailOp = get_stencil_op(rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_FAIL]); - prop.DepthStencil.BackFace.StencilFunc = get_compare_func(rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC]); - prop.DepthStencil.BackFace.StencilPassOp = get_stencil_op(rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZPASS]); - prop.DepthStencil.BackFace.StencilDepthFailOp = get_stencil_op(rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZFAIL]); + prop.DepthStencil.BackFace.StencilFailOp = get_stencil_op(rsx::method_registers.back_stencil_op_fail()); + prop.DepthStencil.BackFace.StencilFunc = get_compare_func(rsx::method_registers.back_stencil_func()); + prop.DepthStencil.BackFace.StencilPassOp = get_stencil_op(rsx::method_registers.back_stencil_op_zpass()); + prop.DepthStencil.BackFace.StencilDepthFailOp = get_stencil_op(rsx::method_registers.back_stencil_op_zfail()); } else { - prop.DepthStencil.BackFace.StencilPassOp = get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_ZPASS]); - prop.DepthStencil.BackFace.StencilDepthFailOp = get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_ZFAIL]); - prop.DepthStencil.BackFace.StencilFailOp = get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_FAIL]); - prop.DepthStencil.BackFace.StencilFunc = get_compare_func(rsx::method_registers[NV4097_SET_STENCIL_FUNC]); + prop.DepthStencil.BackFace.StencilPassOp = get_stencil_op(rsx::method_registers.stencil_op_zpass()); + prop.DepthStencil.BackFace.StencilDepthFailOp = get_stencil_op(rsx::method_registers.stencil_op_zfail()); + prop.DepthStencil.BackFace.StencilFailOp = get_stencil_op(rsx::method_registers.stencil_op_fail()); + prop.DepthStencil.BackFace.StencilFunc = get_compare_func(rsx::method_registers.stencil_func()); } // Sensible default value @@ -202,25 +202,25 @@ void D3D12GSRender::load_program() D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF, }; prop.Rasterization = CD3D12_RASTERIZER_DESC; - - if (!!rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE]) + + if (rsx::method_registers.cull_face_enabled()) { - prop.Rasterization.CullMode = get_cull_face(rsx::method_registers[NV4097_SET_CULL_FACE]); + prop.Rasterization.CullMode = get_cull_face(rsx::method_registers.cull_face_mode()); } - prop.Rasterization.FrontCounterClockwise = get_front_face_ccw(rsx::method_registers[NV4097_SET_FRONT_FACE]); + prop.Rasterization.FrontCounterClockwise = get_front_face_ccw(rsx::method_registers.front_face_mode()); UINT8 mask = 0; - mask |= (rsx::method_registers[NV4097_SET_COLOR_MASK] >> 16) & 0xFF ? D3D12_COLOR_WRITE_ENABLE_RED : 0; - mask |= (rsx::method_registers[NV4097_SET_COLOR_MASK] >> 8) & 0xFF ? D3D12_COLOR_WRITE_ENABLE_GREEN : 0; - mask |= rsx::method_registers[NV4097_SET_COLOR_MASK] & 0xFF ? D3D12_COLOR_WRITE_ENABLE_BLUE : 0; - mask |= (rsx::method_registers[NV4097_SET_COLOR_MASK] >> 24) & 0xFF ? D3D12_COLOR_WRITE_ENABLE_ALPHA : 0; + mask |= rsx::method_registers.color_mask_r() ? D3D12_COLOR_WRITE_ENABLE_RED : 0; + mask |= rsx::method_registers.color_mask_g() ? D3D12_COLOR_WRITE_ENABLE_GREEN : 0; + mask |= rsx::method_registers.color_mask_b() ? D3D12_COLOR_WRITE_ENABLE_BLUE : 0; + mask |= rsx::method_registers.color_mask_a() ? D3D12_COLOR_WRITE_ENABLE_ALPHA : 0; for (unsigned i = 0; i < prop.numMRT; i++) prop.Blend.RenderTarget[i].RenderTargetWriteMask = mask; - if (!!rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE]) + if (rsx::method_registers.restart_index_enabled()) { - rsx::index_array_type index_type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4); + rsx::index_array_type index_type = rsx::method_registers.index_type(); if (index_type == rsx::index_array_type::u32) { prop.CutValue = D3D12_INDEX_BUFFER_STRIP_CUT_VALUE_0xFFFFFFFF; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp index e77875d69a..f3c40593a5 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12RenderTargetSets.cpp @@ -56,21 +56,6 @@ namespace throw EXCEPTION("Wrong color_target (%d)", color_target); } - std::array 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 - { - clear_r / 255.0f, - clear_g / 255.0f, - clear_b / 255.0f, - clear_a / 255.0f - }; - } - u8 get_clear_stencil(u32 register_value) { return register_value & 0xff; @@ -123,8 +108,6 @@ namespace void D3D12GSRender::clear_surface(u32 arg) { - if (!rsx::method_registers[NV4097_SET_SURFACE_FORMAT]) return; - std::chrono::time_point start_duration = std::chrono::system_clock::now(); std::chrono::time_point rtt_duration_start = std::chrono::system_clock::now(); @@ -139,25 +122,32 @@ void D3D12GSRender::clear_surface(u32 arg) if (arg & 0x1) { - u32 clear_depth = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] >> 8; - u32 max_depth_value = get_max_depth_value(m_surface.depth_format); + u32 clear_depth = rsx::method_registers.z_clear_value(); + u32 max_depth_value = get_max_depth_value(rsx::method_registers.surface_depth_fmt()); get_current_resource_storage().command_list->ClearDepthStencilView(m_rtts.current_ds_handle, D3D12_CLEAR_FLAG_DEPTH, clear_depth / (float)max_depth_value, 0, - 1, &get_scissor(rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL], rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL])); + 1, &get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(), rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height())); } if (arg & 0x2) - get_current_resource_storage().command_list->ClearDepthStencilView(m_rtts.current_ds_handle, D3D12_CLEAR_FLAG_STENCIL, 0.f, get_clear_stencil(rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE]), - 1, &get_scissor(rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL], rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL])); + get_current_resource_storage().command_list->ClearDepthStencilView(m_rtts.current_ds_handle, D3D12_CLEAR_FLAG_STENCIL, 0.f, get_clear_stencil(rsx::method_registers.stencil_clear_value()), + 1, &get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(), rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height())); } if (arg & 0xF0) { CD3DX12_CPU_DESCRIPTOR_HANDLE handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(m_rtts.current_rtts_handle); - size_t rtt_index = get_num_rtt(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])); + size_t rtt_index = get_num_rtt(rsx::method_registers.surface_color_target()); get_current_resource_storage().render_targets_descriptors_heap_index += rtt_index; + std::array clear_color = + { + rsx::method_registers.clear_color_r() / 255.f, + rsx::method_registers.clear_color_g() / 255.f, + rsx::method_registers.clear_color_b() / 255.f, + rsx::method_registers.clear_color_a() / 255.f, + }; for (unsigned i = 0; i < rtt_index; i++) - get_current_resource_storage().command_list->ClearRenderTargetView(handle.Offset(i, m_descriptor_stride_rtv), get_clear_color(rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]).data(), - 1, &get_scissor(rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL], rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL])); + get_current_resource_storage().command_list->ClearRenderTargetView(handle.Offset(i, m_descriptor_stride_rtv), clear_color.data(), + 1, &get_scissor(rsx::method_registers.scissor_origin_x(), rsx::method_registers.scissor_origin_y(), rsx::method_registers.scissor_width(), rsx::method_registers.scissor_height())); } std::chrono::time_point end_duration = std::chrono::system_clock::now(); @@ -174,28 +164,27 @@ void D3D12GSRender::clear_surface(u32 arg) void D3D12GSRender::prepare_render_targets(ID3D12GraphicsCommandList *copycmdlist) { - // check if something has changed - u32 surface_format = rsx::method_registers[NV4097_SET_SURFACE_FORMAT]; - // Exit early if there is no rtt changes if (!m_rtts_dirty) return; m_rtts_dirty = false; - - if (m_surface.format != surface_format) - m_surface.unpack(surface_format); - - std::array clear_color = get_clear_color(rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]); + std::array clear_color = + { + rsx::method_registers.clear_color_r() / 255.f, + rsx::method_registers.clear_color_g() / 255.f, + rsx::method_registers.clear_color_b() / 255.f, + rsx::method_registers.clear_color_a() / 255.f, + }; m_rtts.prepare_render_target(copycmdlist, - rsx::method_registers[NV4097_SET_SURFACE_FORMAT], - rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL], rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL], - rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]), + rsx::method_registers.surface_color(), rsx::method_registers.surface_depth_fmt(), + rsx::method_registers.surface_clip_width(), rsx::method_registers.surface_clip_height(), + rsx::method_registers.surface_color_target(), get_color_surface_addresses(), get_zeta_surface_address(), m_device.Get(), clear_color, 1.f, 0); // write descriptors - DXGI_FORMAT dxgi_format = get_color_surface_format(m_surface.color_format); + DXGI_FORMAT dxgi_format = get_color_surface_format(rsx::method_registers.surface_color()); D3D12_RENDER_TARGET_VIEW_DESC rtt_view_desc = {}; rtt_view_desc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; rtt_view_desc.Format = dxgi_format; @@ -203,7 +192,7 @@ void D3D12GSRender::prepare_render_targets(ID3D12GraphicsCommandList *copycmdlis m_rtts.current_rtts_handle = CD3DX12_CPU_DESCRIPTOR_HANDLE(get_current_resource_storage().render_targets_descriptors_heap->GetCPUDescriptorHandleForHeapStart()) .Offset((INT)get_current_resource_storage().render_targets_descriptors_heap_index * m_descriptor_stride_rtv); size_t rtt_index = 0; - for (u8 i : get_rtt_indexes(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))) + for (u8 i : get_rtt_indexes(rsx::method_registers.surface_color_target())) { if (std::get<1>(m_rtts.m_bound_render_targets[i]) == nullptr) continue; @@ -219,14 +208,14 @@ void D3D12GSRender::prepare_render_targets(ID3D12GraphicsCommandList *copycmdlis .Offset((INT)get_current_resource_storage().depth_stencil_descriptor_heap_index * m_descriptor_stride_dsv); get_current_resource_storage().depth_stencil_descriptor_heap_index += 1; D3D12_DEPTH_STENCIL_VIEW_DESC depth_stencil_view_desc = {}; - depth_stencil_view_desc.Format = get_depth_stencil_surface_format(m_surface.depth_format); + depth_stencil_view_desc.Format = get_depth_stencil_surface_format(rsx::method_registers.surface_depth_fmt()); depth_stencil_view_desc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D; m_device->CreateDepthStencilView(std::get<1>(m_rtts.m_bound_depth_stencil), &depth_stencil_view_desc, m_rtts.current_ds_handle); } void D3D12GSRender::set_rtt_and_ds(ID3D12GraphicsCommandList *command_list) { - UINT num_rtt = get_num_rtt(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])); + UINT num_rtt = get_num_rtt(rsx::method_registers.surface_color_target()); D3D12_CPU_DESCRIPTOR_HANDLE* ds_handle = (std::get<1>(m_rtts.m_bound_depth_stencil) != nullptr) ? &m_rtts.current_ds_handle : nullptr; command_list->OMSetRenderTargets((UINT)num_rtt, &m_rtts.current_rtts_handle, true, ds_handle); } @@ -250,8 +239,8 @@ namespace rsx::surface_color_format color_surface_format ) { - int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; - int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; + int clip_w = rsx::method_registers.surface_clip_width(); + int clip_h = rsx::method_registers.surface_clip_height(); DXGI_FORMAT dxgi_format = get_color_surface_format(color_surface_format); size_t row_pitch = get_aligned_pitch(color_surface_format, clip_w); @@ -300,42 +289,25 @@ void D3D12GSRender::copy_render_target_to_dma_location() // Add all buffer write // Cell can't make any assumption about readyness of color/depth buffer // Except when a semaphore is written by RSX - int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; - int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; + int clip_w = rsx::method_registers.surface_clip_width(); + int clip_h = rsx::method_registers.surface_clip_height(); size_t depth_row_pitch = align(clip_w * 4, 256); size_t depth_buffer_offset_in_heap = 0; - u32 context_dma_color[] = - { - rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_A], - rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_B], - rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_C], - rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_D], - }; - u32 m_context_dma_z = rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]; - - u32 offset_color[] = - { - rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], - rsx::method_registers[NV4097_SET_SURFACE_COLOR_BOFFSET], - rsx::method_registers[NV4097_SET_SURFACE_COLOR_COFFSET], - rsx::method_registers[NV4097_SET_SURFACE_COLOR_DOFFSET] - }; - u32 offset_zeta = rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET]; u32 address_color[] = { - rsx::get_address(offset_color[0], context_dma_color[0]), - rsx::get_address(offset_color[1], context_dma_color[1]), - rsx::get_address(offset_color[2], context_dma_color[2]), - rsx::get_address(offset_color[3], context_dma_color[3]), + rsx::get_address(rsx::method_registers.surface_a_offset(), rsx::method_registers.surface_a_dma()), + rsx::get_address(rsx::method_registers.surface_b_offset(), rsx::method_registers.surface_b_dma()), + rsx::get_address(rsx::method_registers.surface_c_offset(), rsx::method_registers.surface_c_dma()), + rsx::get_address(rsx::method_registers.surface_d_offset(), rsx::method_registers.surface_d_dma()), }; - u32 address_z = rsx::get_address(offset_zeta, m_context_dma_z); + u32 address_z = rsx::get_address(rsx::method_registers.surface_z_offset(), rsx::method_registers.surface_z_dma()); bool need_transfer = false; - if (m_context_dma_z && g_cfg_rsx_write_depth_buffer) + if (rsx::method_registers.surface_z_dma() && g_cfg_rsx_write_depth_buffer) { get_current_resource_storage().command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(std::get<1>(m_rtts.m_bound_depth_stencil), D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_COPY_SOURCE)); get_current_resource_storage().command_list->CopyTextureRegion(&CD3DX12_TEXTURE_COPY_LOCATION(m_readback_resources.get_heap(), { depth_buffer_offset_in_heap,{ DXGI_FORMAT_R32_TYPELESS, (UINT)clip_w, (UINT)clip_h, 1, (UINT)depth_row_pitch } }), 0, 0, 0, @@ -349,11 +321,11 @@ void D3D12GSRender::copy_render_target_to_dma_location() size_t color_buffer_offset_in_heap[4]; if (g_cfg_rsx_write_color_buffers) { - for (u8 i : get_rtt_indexes(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))) + for (u8 i : get_rtt_indexes(rsx::method_registers.surface_color_target())) { if (!address_color[i]) continue; - color_buffer_offset_in_heap[i] = download_to_readback_buffer(m_device.Get(), get_current_resource_storage().command_list.Get(), m_readback_resources, std::get<1>(m_rtts.m_bound_render_targets[i]), m_surface.color_format); + color_buffer_offset_in_heap[i] = download_to_readback_buffer(m_device.Get(), get_current_resource_storage().command_list.Get(), m_readback_resources, std::get<1>(m_rtts.m_bound_render_targets[i]), rsx::method_registers.surface_color()); invalidate_address(address_color[i]); need_transfer = true; } @@ -390,8 +362,8 @@ void D3D12GSRender::copy_render_target_to_dma_location() if (g_cfg_rsx_write_color_buffers) { - size_t srcPitch = get_aligned_pitch(m_surface.color_format, clip_w); - size_t dstPitch = get_packed_pitch(m_surface.color_format, clip_w); + size_t srcPitch = get_aligned_pitch(rsx::method_registers.surface_color(), clip_w); + size_t dstPitch = get_packed_pitch(rsx::method_registers.surface_color(), clip_w); void *dest_buffer[] = { @@ -401,7 +373,7 @@ void D3D12GSRender::copy_render_target_to_dma_location() vm::base(address_color[3]), }; - for (u8 i : get_rtt_indexes(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]))) + for (u8 i : get_rtt_indexes(rsx::method_registers.surface_color_target())) { if (!address_color[i]) continue; @@ -413,19 +385,15 @@ void D3D12GSRender::copy_render_target_to_dma_location() std::array, 4> D3D12GSRender::copy_render_targets_to_memory() { - int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; - int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; - rsx::surface_info surface = {}; - surface.unpack(rsx::method_registers[NV4097_SET_SURFACE_FORMAT]); - return m_rtts.get_render_targets_data(surface.color_format, clip_w, clip_h, m_device.Get(), m_command_queue.Get(), m_readback_resources, get_current_resource_storage()); + int clip_w = rsx::method_registers.surface_clip_width(); + int clip_h = rsx::method_registers.surface_clip_height(); + return m_rtts.get_render_targets_data(rsx::method_registers.surface_color(), clip_w, clip_h, m_device.Get(), m_command_queue.Get(), m_readback_resources, get_current_resource_storage()); } std::array, 2> D3D12GSRender::copy_depth_stencil_buffer_to_memory() { - int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; - int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; - rsx::surface_info surface = {}; - surface.unpack(rsx::method_registers[NV4097_SET_SURFACE_FORMAT]); - return m_rtts.get_depth_stencil_data(surface.depth_format, clip_w, clip_h, m_device.Get(), m_command_queue.Get(), m_readback_resources, get_current_resource_storage()); + int clip_w = rsx::method_registers.surface_clip_width(); + int clip_h = rsx::method_registers.surface_clip_height(); + return m_rtts.get_depth_stencil_data(rsx::method_registers.surface_depth_fmt(), clip_w, clip_h, m_device.Get(), m_command_queue.Get(), m_readback_resources, get_current_resource_storage()); } #endif diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index bcff1c267d..c60e2121f8 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -6,6 +6,7 @@ #include "../Common/TextureUtils.h" // For clarity this code deals with texture but belongs to D3D12GSRender class #include "D3D12Formats.h" +#include "../rsx_methods.h" namespace { @@ -174,7 +175,7 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz continue; m_textures_dirty[i] = false; - if (!textures[i].enabled()) + if (!rsx::method_registers.fragment_textures[i].enabled()) { // Now fill remaining texture slots with dummy texture/sampler @@ -205,13 +206,13 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz continue; } - size_t w = textures[i].width(), h = textures[i].height(); + size_t w = rsx::method_registers.fragment_textures[i].width(), h = rsx::method_registers.fragment_textures[i].height(); // if (!w || !h) continue; - const u32 texaddr = rsx::get_address(textures[i].offset(), textures[i].location()); + const u32 texaddr = rsx::get_address(rsx::method_registers.fragment_textures[i].offset(), rsx::method_registers.fragment_textures[i].location()); - const u8 format = textures[i].format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); - bool is_swizzled = !(textures[i].format() & CELL_GCM_TEXTURE_LN); + const u8 format = rsx::method_registers.fragment_textures[i].format() & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); + bool is_swizzled = !(rsx::method_registers.fragment_textures[i].format() & CELL_GCM_TEXTURE_LN); ID3D12Resource *vram_texture; std::pair > *cached_texture = m_texture_cache.find_data_if_available(texaddr); @@ -225,13 +226,13 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz { is_depth_stencil_texture = true; } - else if (cached_texture != nullptr && (cached_texture->first == texture_entry(format, w, h, textures[i].depth(), textures[i].get_exact_mipmap_count()))) + else if (cached_texture != nullptr && (cached_texture->first == texture_entry(format, w, h, rsx::method_registers.fragment_textures[i].depth(), rsx::method_registers.fragment_textures[i].get_exact_mipmap_count()))) { if (cached_texture->first.m_is_dirty) { command_list->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(cached_texture->second.Get(), D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_COPY_DEST)); - update_existing_texture(textures[i], command_list, m_buffer_data, cached_texture->second.Get()); - m_texture_cache.protect_data(texaddr, texaddr, get_texture_size(textures[i])); + update_existing_texture(rsx::method_registers.fragment_textures[i], command_list, m_buffer_data, cached_texture->second.Get()); + m_texture_cache.protect_data(texaddr, texaddr, get_texture_size(rsx::method_registers.fragment_textures[i])); } vram_texture = cached_texture->second.Get(); } @@ -239,14 +240,14 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz { if (cached_texture != nullptr) get_current_resource_storage().dirty_textures.push_back(m_texture_cache.remove_from_cache(texaddr)); - ComPtr tex = upload_single_texture(textures[i], m_device.Get(), command_list, m_buffer_data); + ComPtr tex = upload_single_texture(rsx::method_registers.fragment_textures[i], m_device.Get(), command_list, m_buffer_data); std::wstring name = L"texture_@" + std::to_wstring(texaddr); tex->SetName(name.c_str()); vram_texture = tex.Get(); - m_texture_cache.store_and_protect_data(texaddr, texaddr, get_texture_size(textures[i]), format, w, h, textures[i].depth(), textures[i].get_exact_mipmap_count(), tex); + m_texture_cache.store_and_protect_data(texaddr, texaddr, get_texture_size(rsx::method_registers.fragment_textures[i]), format, w, h, rsx::method_registers.fragment_textures[i].depth(), rsx::method_registers.fragment_textures[i].get_exact_mipmap_count(), tex); } - D3D12_SHADER_RESOURCE_VIEW_DESC shared_resource_view_desc = get_srv_descriptor_with_dimensions(textures[i]); + D3D12_SHADER_RESOURCE_VIEW_DESC shared_resource_view_desc = get_srv_descriptor_with_dimensions(rsx::method_registers.fragment_textures[i]); shared_resource_view_desc.Format = get_texture_format(format); switch (format) @@ -339,10 +340,10 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz { - u8 remap_a = textures[i].remap() & 0x3; - u8 remap_r = (textures[i].remap() >> 2) & 0x3; - u8 remap_g = (textures[i].remap() >> 4) & 0x3; - u8 remap_b = (textures[i].remap() >> 6) & 0x3; + u8 remap_a = rsx::method_registers.fragment_textures[i].remap() & 0x3; + u8 remap_r = (rsx::method_registers.fragment_textures[i].remap() >> 2) & 0x3; + u8 remap_g = (rsx::method_registers.fragment_textures[i].remap() >> 4) & 0x3; + u8 remap_b = (rsx::method_registers.fragment_textures[i].remap() >> 6) & 0x3; if (is_render_target) { @@ -399,7 +400,7 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz .Offset((UINT)i, m_descriptor_stride_srv_cbv_uav) ); - m_device->CreateSampler(&get_sampler_desc(textures[i]), + m_device->CreateSampler(&get_sampler_desc(rsx::method_registers.fragment_textures[i]), CD3DX12_CPU_DESCRIPTOR_HANDLE(m_current_sampler_descriptors->GetCPUDescriptorHandleForHeapStart()) .Offset((UINT)i, m_descriptor_stride_samplers)); } diff --git a/rpcs3/Emu/RSX/GCM.cpp b/rpcs3/Emu/RSX/GCM.cpp index 2910594db2..30ba527f9a 100644 --- a/rpcs3/Emu/RSX/GCM.cpp +++ b/rpcs3/Emu/RSX/GCM.cpp @@ -1036,6 +1036,260 @@ rsx::surface_color_format rsx::to_surface_color_format(u8 in) throw EXCEPTION("unknow surface color format %x", in); } +rsx::stencil_op rsx::to_stencil_op(u16 in) +{ + switch (in) + { + case CELL_GCM_KEEP: return rsx::stencil_op::keep; + case CELL_GCM_REPLACE: return rsx::stencil_op::replace; + case CELL_GCM_INCR: return rsx::stencil_op::incr; + case CELL_GCM_DECR: return rsx::stencil_op::decr; + case CELL_GCM_INCR_WRAP: return rsx::stencil_op::incr_wrap; + case CELL_GCM_DECR_WRAP: return rsx::stencil_op::decr_wrap; + case CELL_GCM_ZERO: return rsx::stencil_op::zero; + } + throw EXCEPTION("unknow stencil op %x", in); +} + +rsx::blend_equation rsx::to_blend_equation(u16 in) +{ + switch (in) + { + case CELL_GCM_FUNC_ADD: return rsx::blend_equation::add; + case CELL_GCM_MIN: return rsx::blend_equation::min; + case CELL_GCM_MAX: return rsx::blend_equation::max; + case CELL_GCM_FUNC_SUBTRACT: return rsx::blend_equation::substract; + case CELL_GCM_FUNC_REVERSE_SUBTRACT: return rsx::blend_equation::reverse_substract; + case CELL_GCM_FUNC_REVERSE_SUBTRACT_SIGNED: return rsx::blend_equation::reverse_substract_signed; + case CELL_GCM_FUNC_ADD_SIGNED: return rsx::blend_equation::add_signed; + case CELL_GCM_FUNC_REVERSE_ADD_SIGNED: return rsx::blend_equation::reverse_add_signed; + } + throw EXCEPTION("unknow blend eq %x", in); +} + +rsx::blend_factor rsx::to_blend_factor(u16 in) +{ + switch (in) + { + case CELL_GCM_ZERO: return rsx::blend_factor::zero; + case CELL_GCM_ONE: return rsx::blend_factor::one; + case CELL_GCM_SRC_COLOR: return rsx::blend_factor::src_color; + case CELL_GCM_ONE_MINUS_SRC_COLOR: return rsx::blend_factor::one_minus_src_color; + case CELL_GCM_SRC_ALPHA: return rsx::blend_factor::src_alpha; + case CELL_GCM_ONE_MINUS_SRC_ALPHA: return rsx::blend_factor::one_minus_src_alpha; + case CELL_GCM_DST_ALPHA: return rsx::blend_factor::dst_alpha; + case CELL_GCM_ONE_MINUS_DST_ALPHA: return rsx::blend_factor::one_minus_dst_alpha; + case CELL_GCM_DST_COLOR: return rsx::blend_factor::dst_color; + case CELL_GCM_ONE_MINUS_DST_COLOR: return rsx::blend_factor::one_minus_dst_color; + case CELL_GCM_SRC_ALPHA_SATURATE: return rsx::blend_factor::src_alpha_saturate; + case CELL_GCM_CONSTANT_COLOR: return rsx::blend_factor::constant_color; + case CELL_GCM_ONE_MINUS_CONSTANT_COLOR: return rsx::blend_factor::one_minus_constant_color; + case CELL_GCM_CONSTANT_ALPHA: return rsx::blend_factor::constant_alpha; + case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA: return rsx::blend_factor::one_minus_constant_alpha; + } + throw EXCEPTION("unknow blend factor %x", in); +} + +rsx::logic_op rsx::to_logic_op(u16 in) +{ + switch (in) + { + case CELL_GCM_CLEAR: return rsx::logic_op::logic_clear; + case CELL_GCM_AND: return rsx::logic_op::logic_and; + case CELL_GCM_AND_REVERSE: return rsx::logic_op::logic_and_reverse; + case CELL_GCM_COPY: return rsx::logic_op::logic_copy; + case CELL_GCM_AND_INVERTED: return rsx::logic_op::logic_and_inverted; + case CELL_GCM_NOOP: return rsx::logic_op::logic_noop; + case CELL_GCM_XOR: return rsx::logic_op::logic_xor; + case CELL_GCM_OR: return rsx::logic_op::logic_or; + case CELL_GCM_NOR: return rsx::logic_op::logic_nor; + case CELL_GCM_EQUIV: return rsx::logic_op::logic_equiv; + case CELL_GCM_INVERT: return rsx::logic_op::logic_invert; + case CELL_GCM_OR_REVERSE: return rsx::logic_op::logic_or_reverse; + case CELL_GCM_COPY_INVERTED: return rsx::logic_op::logic_copy_inverted; + case CELL_GCM_OR_INVERTED: return rsx::logic_op::logic_or_inverted; + case CELL_GCM_NAND: return rsx::logic_op::logic_nand; + case CELL_GCM_SET: return rsx::logic_op::logic_set; + } + throw EXCEPTION("unknow logic op %x", in); +} + +rsx::front_face rsx::to_front_face(u16 in) +{ + switch (in) + { + case CELL_GCM_CW: return rsx::front_face::cw; + case CELL_GCM_CCW: return rsx::front_face::ccw; + } + throw EXCEPTION("unknow front face %x", in); +} + +rsx::cull_face rsx::to_cull_face(u16 in) +{ + switch (in) + { + case CELL_GCM_FRONT_AND_BACK: return rsx::cull_face::front_and_back; + case CELL_GCM_FRONT: return rsx::cull_face::front; + case CELL_GCM_BACK: return rsx::cull_face::back; + } + throw EXCEPTION("unknow cull face %x", in); +} + +enum +{ + CELL_GCM_TRANSFER_ORIGIN_CENTER = 1, + CELL_GCM_TRANSFER_ORIGIN_CORNER = 2, + + CELL_GCM_TRANSFER_INTERPOLATOR_ZOH = 0, + CELL_GCM_TRANSFER_INTERPOLATOR_FOH = 1, +}; + +rsx::blit_engine::transfer_origin rsx::blit_engine::to_transfer_origin(u8 in) +{ + switch (in) + { + case CELL_GCM_TRANSFER_ORIGIN_CENTER: return rsx::blit_engine::transfer_origin::center; + case CELL_GCM_TRANSFER_ORIGIN_CORNER: return rsx::blit_engine::transfer_origin::corner; + } + throw EXCEPTION("unknow tranfer origin %x", in); +} + +rsx::blit_engine::transfer_interpolator rsx::blit_engine::to_transfer_interpolator(u8 in) +{ + switch (in) + { + case CELL_GCM_TRANSFER_INTERPOLATOR_ZOH: return rsx::blit_engine::transfer_interpolator::zoh; + case CELL_GCM_TRANSFER_INTERPOLATOR_FOH: return rsx::blit_engine::transfer_interpolator::foh; + } + throw EXCEPTION("unknow tranfer interpolator %x", in); +} + +enum +{ + CELL_GCM_TRANSFER_OPERATION_SRCCOPY_AND = 0, + CELL_GCM_TRANSFER_OPERATION_ROP_AND = 1, + CELL_GCM_TRANSFER_OPERATION_BLEND_AND = 2, + CELL_GCM_TRANSFER_OPERATION_SRCCOPY = 3, + CELL_GCM_TRANSFER_OPERATION_SRCCOPY_PREMULT = 4, + CELL_GCM_TRANSFER_OPERATION_BLEND_PREMULT = 5, +}; + +rsx::blit_engine::transfer_operation rsx::blit_engine::to_transfer_operation(u8 in) +{ + switch (in) + { + case CELL_GCM_TRANSFER_OPERATION_SRCCOPY_AND: return rsx::blit_engine::transfer_operation::srccopy_and; + case CELL_GCM_TRANSFER_OPERATION_ROP_AND: return rsx::blit_engine::transfer_operation::rop_and; + case CELL_GCM_TRANSFER_OPERATION_BLEND_AND: return rsx::blit_engine::transfer_operation::blend_and; + case CELL_GCM_TRANSFER_OPERATION_SRCCOPY: return rsx::blit_engine::transfer_operation::srccopy; + case CELL_GCM_TRANSFER_OPERATION_SRCCOPY_PREMULT: return rsx::blit_engine::transfer_operation::srccopy_premult; + case CELL_GCM_TRANSFER_OPERATION_BLEND_PREMULT: return rsx::blit_engine::transfer_operation::blend_premult; + } + throw EXCEPTION("unknow tranfer operation %x", in); +} + +enum +{ + CELL_GCM_TRANSFER_SCALE_FORMAT_A1R5G5B5 = 1, + CELL_GCM_TRANSFER_SCALE_FORMAT_X1R5G5B5 = 2, + CELL_GCM_TRANSFER_SCALE_FORMAT_A8R8G8B8 = 3, + CELL_GCM_TRANSFER_SCALE_FORMAT_X8R8G8B8 = 4, + CELL_GCM_TRANSFER_SCALE_FORMAT_CR8YB8CB8YA8 = 5, + CELL_GCM_TRANSFER_SCALE_FORMAT_YB8CR8YA8CB8 = 6, + CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5 = 7, + CELL_GCM_TRANSFER_SCALE_FORMAT_Y8 = 8, + CELL_GCM_TRANSFER_SCALE_FORMAT_AY8 = 9, + CELL_GCM_TRANSFER_SCALE_FORMAT_EYB8ECR8EYA8ECB8 = 10, + CELL_GCM_TRANSFER_SCALE_FORMAT_ECR8EYB8ECB8EYA8 = 11, + CELL_GCM_TRANSFER_SCALE_FORMAT_A8B8G8R8 = 12, + CELL_GCM_TRANSFER_SCALE_FORMAT_X8B8G8R8 = 13, +}; + +rsx::blit_engine::transfer_source_format rsx::blit_engine::to_transfer_source_format(u8 in) +{ + switch (in) + { + case CELL_GCM_TRANSFER_SCALE_FORMAT_A1R5G5B5: return rsx::blit_engine::transfer_source_format::a1r5g5b5; + case CELL_GCM_TRANSFER_SCALE_FORMAT_X1R5G5B5: return rsx::blit_engine::transfer_source_format::x1r5g5b5; + case CELL_GCM_TRANSFER_SCALE_FORMAT_A8R8G8B8: return rsx::blit_engine::transfer_source_format::a8r8g8b8; + case CELL_GCM_TRANSFER_SCALE_FORMAT_X8R8G8B8: return rsx::blit_engine::transfer_source_format::x8r8g8b8; + case CELL_GCM_TRANSFER_SCALE_FORMAT_CR8YB8CB8YA8: return rsx::blit_engine::transfer_source_format::cr8yb8cb8ya8; + case CELL_GCM_TRANSFER_SCALE_FORMAT_YB8CR8YA8CB8: return rsx::blit_engine::transfer_source_format::yb8cr8ya8cb8; + case CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5: return rsx::blit_engine::transfer_source_format::r5g6b5; + case CELL_GCM_TRANSFER_SCALE_FORMAT_Y8: return rsx::blit_engine::transfer_source_format::y8; + case CELL_GCM_TRANSFER_SCALE_FORMAT_AY8: return rsx::blit_engine::transfer_source_format::ay8; + case CELL_GCM_TRANSFER_SCALE_FORMAT_EYB8ECR8EYA8ECB8: return rsx::blit_engine::transfer_source_format::eyb8ecr8eya8ecb8; + case CELL_GCM_TRANSFER_SCALE_FORMAT_ECR8EYB8ECB8EYA8: return rsx::blit_engine::transfer_source_format::ecr8eyb8ecb8eya8; + case CELL_GCM_TRANSFER_SCALE_FORMAT_A8B8G8R8: return rsx::blit_engine::transfer_source_format::a8b8g8r8; + case CELL_GCM_TRANSFER_SCALE_FORMAT_X8B8G8R8: return rsx::blit_engine::transfer_source_format::x8b8g8r8; + } + throw EXCEPTION("unknow transfer source format %x", in); +} + +enum +{ + // Destination Format conversions + CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 = 4, + CELL_GCM_TRANSFER_SURFACE_FORMAT_A8R8G8B8 = 10, + CELL_GCM_TRANSFER_SURFACE_FORMAT_Y32 = 11, +}; + +rsx::blit_engine::transfer_destination_format rsx::blit_engine::to_transfer_destination_format(u8 in) +{ + switch (in) + { + case CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5: return rsx::blit_engine::transfer_destination_format::r5g6b5; + case CELL_GCM_TRANSFER_SURFACE_FORMAT_A8R8G8B8: return rsx::blit_engine::transfer_destination_format::a8r8g8b8; + case CELL_GCM_TRANSFER_SURFACE_FORMAT_Y32: return rsx::blit_engine::transfer_destination_format::y32; + } + throw EXCEPTION("unknow transfer destination format %x", in); +} + +enum +{ + CELL_GCM_CONTEXT_SURFACE2D = 0x313371C3, + CELL_GCM_CONTEXT_SWIZZLE2D = 0x31337A73, +}; + +rsx::blit_engine::context_surface rsx::blit_engine::to_context_surface(u32 in) +{ + switch (in) + { + case CELL_GCM_CONTEXT_SURFACE2D: return rsx::blit_engine::context_surface::surface2d; + case CELL_GCM_CONTEXT_SWIZZLE2D: return rsx::blit_engine::context_surface::swizzle2d; + } + throw EXCEPTION("unknow context surface %x", in); +} + +rsx::blit_engine::context_dma rsx::blit_engine::to_context_dma(u32 in) +{ + switch (in) + { + case CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT: return rsx::blit_engine::context_dma::to_memory_get_report; + case CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_MAIN: return rsx::blit_engine::context_dma::report_location_main; + } + throw EXCEPTION("unknow context dma %x", in); +} + +enum +{ + CELL_GCM_USER_CLIP_PLANE_DISABLE = 0, + CELL_GCM_USER_CLIP_PLANE_ENABLE_LT = 1, + CELL_GCM_USER_CLIP_PLANE_ENABLE_GE = 2, +}; + +rsx::user_clip_plane_op rsx::to_user_clip_plane_op(u8 in) +{ + switch (in) + { + case CELL_GCM_USER_CLIP_PLANE_DISABLE: return rsx::user_clip_plane_op::disable; + case CELL_GCM_USER_CLIP_PLANE_ENABLE_LT: return rsx::user_clip_plane_op::less_than; + case CELL_GCM_USER_CLIP_PLANE_ENABLE_GE: return rsx::user_clip_plane_op::greather_or_equal; + } + throw EXCEPTION("unknow user clip plane %x", in); +} + + // Various parameter pretty printing function namespace { diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index 82c583c876..37e79f26ac 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -212,6 +212,178 @@ namespace rsx }; texture_magnify_filter to_texture_magnify_filter(u8 in); + + enum class stencil_op : u8 + { + keep, + zero, + replace, + incr, + decr, + invert, + incr_wrap, + decr_wrap, + }; + + stencil_op to_stencil_op(u16 in); + + enum class blend_equation : u8 + { + add, + min, + max, + substract, + reverse_substract, + reverse_substract_signed, + add_signed, + reverse_add_signed, + }; + + blend_equation to_blend_equation(u16 in); + + enum class blend_factor : u8 + { + zero, + one, + src_color, + one_minus_src_color, + dst_color, + one_minus_dst_color, + src_alpha, + one_minus_src_alpha, + dst_alpha, + one_minus_dst_alpha, + src_alpha_saturate, + constant_color, + one_minus_constant_color, + constant_alpha, + one_minus_constant_alpha, + }; + + blend_factor to_blend_factor(u16 in); + + enum class logic_op : u8 + { + logic_clear, + logic_and, + logic_and_reverse, + logic_copy, + logic_and_inverted, + logic_noop, + logic_xor, + logic_or, + logic_nor, + logic_equiv, + logic_invert, + logic_or_reverse, + logic_copy_inverted, + logic_or_inverted, + logic_nand, + logic_set, + }; + + logic_op to_logic_op(u16 in); + + enum class front_face : u8 + { + cw, /// clockwise + ccw /// counter clockwise + }; + + front_face to_front_face(u16 in); + + enum class cull_face : u8 + { + front, + back, + front_and_back, + }; + + cull_face to_cull_face(u16 in); + + enum class user_clip_plane_op : u8 + { + disable, + less_than, + greather_or_equal, + }; + + user_clip_plane_op to_user_clip_plane_op(u8 in); + + namespace blit_engine + { + enum class transfer_origin : u8 + { + center, + corner, + }; + + transfer_origin to_transfer_origin(u8 in); + + enum class transfer_interpolator : u8 + { + zoh, + foh, + }; + + transfer_interpolator to_transfer_interpolator(u8 in); + + enum class transfer_operation : u8 + { + srccopy_and, + rop_and, + blend_and, + srccopy, + srccopy_premult, + blend_premult, + }; + + transfer_operation to_transfer_operation(u8 in); + + enum class transfer_source_format : u8 + { + a1r5g5b5, + x1r5g5b5, + a8r8g8b8, + x8r8g8b8, + cr8yb8cb8ya8, + yb8cr8ya8cb8, + r5g6b5, + y8, + ay8, + eyb8ecr8eya8ecb8, + ecr8eyb8ecb8eya8, + a8b8g8r8, + x8b8g8r8, + }; + + transfer_source_format to_transfer_source_format(u8 in); + + enum class transfer_destination_format : u8 + { + r5g6b5, + a8r8g8b8, + y32, + }; + + transfer_destination_format to_transfer_destination_format(u8 in); + + enum class context_surface : u8 + { + surface2d, + swizzle2d, + }; + + context_surface to_context_surface(u32 in); + + enum class context_dma : u8 + { + to_memory_get_report, + report_location_main, + }; + + context_dma to_context_dma(u32 in); + } } enum @@ -298,43 +470,6 @@ enum CELL_GCM_SURFACE_SWIZZLE = 2, }; -enum -{ - // Transfer operations - CELL_GCM_TRANSFER_OPERATION_SRCCOPY_AND = 0, - CELL_GCM_TRANSFER_OPERATION_ROP_AND = 1, - CELL_GCM_TRANSFER_OPERATION_BLEND_AND = 2, - CELL_GCM_TRANSFER_OPERATION_SRCCOPY = 3, - CELL_GCM_TRANSFER_OPERATION_SRCCOPY_PREMULT = 4, - CELL_GCM_TRANSFER_OPERATION_BLEND_PREMULT = 5, - - CELL_GCM_TRANSFER_ORIGIN_CENTER = 1, - CELL_GCM_TRANSFER_ORIGIN_CORNER = 2, - - CELL_GCM_TRANSFER_INTERPOLATOR_ZOH = 0, - CELL_GCM_TRANSFER_INTERPOLATOR_FOH = 1, - - // Destination Format conversions - CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 = 4, - CELL_GCM_TRANSFER_SURFACE_FORMAT_A8R8G8B8 = 10, - CELL_GCM_TRANSFER_SURFACE_FORMAT_Y32 = 11, - - // Source Format conversions - CELL_GCM_TRANSFER_SCALE_FORMAT_A1R5G5B5 = 1, - CELL_GCM_TRANSFER_SCALE_FORMAT_X1R5G5B5 = 2, - CELL_GCM_TRANSFER_SCALE_FORMAT_A8R8G8B8 = 3, - CELL_GCM_TRANSFER_SCALE_FORMAT_X8R8G8B8 = 4, - CELL_GCM_TRANSFER_SCALE_FORMAT_CR8YB8CB8YA8 = 5, - CELL_GCM_TRANSFER_SCALE_FORMAT_YB8CR8YA8CB8 = 6, - CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5 = 7, - CELL_GCM_TRANSFER_SCALE_FORMAT_Y8 = 8, - CELL_GCM_TRANSFER_SCALE_FORMAT_AY8 = 9, - CELL_GCM_TRANSFER_SCALE_FORMAT_EYB8ECR8EYA8ECB8 = 10, - CELL_GCM_TRANSFER_SCALE_FORMAT_ECR8EYB8ECB8EYA8 = 11, - CELL_GCM_TRANSFER_SCALE_FORMAT_A8B8G8R8 = 12, - CELL_GCM_TRANSFER_SCALE_FORMAT_X8B8G8R8 = 13, -}; - enum { CELL_GCM_TEXTURE_UNSIGNED_REMAP_NORMAL = 0, @@ -567,10 +702,6 @@ enum CELL_GCM_TRUE = 1, CELL_GCM_FALSE = 0, - - CELL_GCM_USER_CLIP_PLANE_DISABLE = 0, - CELL_GCM_USER_CLIP_PLANE_ENABLE_LT = 1, - CELL_GCM_USER_CLIP_PLANE_ENABLE_GE = 2, }; enum @@ -594,10 +725,8 @@ enum { CELL_GCM_CONTEXT_DMA_MEMORY_FRAME_BUFFER = 0xFEED0000, // Local memory CELL_GCM_CONTEXT_DMA_MEMORY_HOST_BUFFER = 0xFEED0001, // Main memory - CELL_GCM_CONTEXT_SURFACE2D = 0x313371C3, - CELL_GCM_CONTEXT_SWIZZLE2D = 0x31337A73, - CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT = 0x66626660, - CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_MAIN = 0xBAD68000, + CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT = 0x66626660, + CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_MAIN = 0xBAD68000, CELL_GCM_CONTEXT_DMA_NOTIFY_MAIN_0 = 0x6660420F, }; diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index d038f7a359..92c21af251 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -71,6 +71,125 @@ u32 GLGSRender::enable(u32 condition, u32 cap, u32 index) extern CellGcmContextData current_context; +namespace +{ + GLenum comparaison_op(rsx::comparaison_function op) + { + switch (op) + { + case rsx::comparaison_function::never: return GL_NEVER; + case rsx::comparaison_function::less: return GL_LESS; + case rsx::comparaison_function::equal: return GL_EQUAL; + case rsx::comparaison_function::less_or_equal: return GL_LEQUAL; + case rsx::comparaison_function::greater: return GL_GREATER; + case rsx::comparaison_function::not_equal: return GL_NOTEQUAL; + case rsx::comparaison_function::greater_or_equal: return GL_GEQUAL; + case rsx::comparaison_function::always: return GL_ALWAYS; + } + throw; + } + + GLenum stencil_op(rsx::stencil_op op) + { + switch (op) + { + case rsx::stencil_op::keep: return GL_KEEP; + case rsx::stencil_op::zero: return GL_ZERO; + case rsx::stencil_op::replace: return GL_REPLACE; + case rsx::stencil_op::incr: return GL_INCR; + case rsx::stencil_op::decr: return GL_DECR; + case rsx::stencil_op::incr_wrap: return GL_INCR_WRAP; + case rsx::stencil_op::decr_wrap: return GL_DECR_WRAP; + } + throw; + } + + GLenum blend_equation(rsx::blend_equation op) + { + switch (op) + { + // Note : maybe add is signed on gl + case rsx::blend_equation::add: return GL_FUNC_ADD; + case rsx::blend_equation::min: return GL_MIN; + case rsx::blend_equation::max: return GL_MAX; + case rsx::blend_equation::substract: return GL_FUNC_SUBTRACT; + case rsx::blend_equation::reverse_substract: return GL_FUNC_REVERSE_SUBTRACT; + case rsx::blend_equation::reverse_substract_signed: throw "unsupported"; + case rsx::blend_equation::add_signed: throw "unsupported"; + case rsx::blend_equation::reverse_add_signed: throw "unsupported"; + } + throw; + } + + GLenum blend_factor(rsx::blend_factor op) + { + switch (op) + { + case rsx::blend_factor::zero: return GL_ZERO; + case rsx::blend_factor::one: return GL_ONE; + case rsx::blend_factor::src_color: return GL_SRC_COLOR; + case rsx::blend_factor::one_minus_src_color: return GL_ONE_MINUS_SRC_COLOR; + case rsx::blend_factor::dst_color: return GL_DST_COLOR; + case rsx::blend_factor::one_minus_dst_color: return GL_ONE_MINUS_DST_COLOR; + case rsx::blend_factor::src_alpha: return GL_SRC_ALPHA; + case rsx::blend_factor::one_minus_src_alpha: return GL_ONE_MINUS_SRC_ALPHA; + case rsx::blend_factor::dst_alpha: return GL_DST_ALPHA; + case rsx::blend_factor::one_minus_dst_alpha: return GL_ONE_MINUS_DST_ALPHA; + case rsx::blend_factor::src_alpha_saturate: return GL_SRC_ALPHA_SATURATE; + case rsx::blend_factor::constant_color: return GL_CONSTANT_COLOR; + case rsx::blend_factor::one_minus_constant_color: return GL_ONE_MINUS_CONSTANT_COLOR; + case rsx::blend_factor::constant_alpha: return GL_CONSTANT_ALPHA; + case rsx::blend_factor::one_minus_constant_alpha: return GL_ONE_MINUS_CONSTANT_ALPHA; + } + throw; + } + + GLenum logic_op(rsx::logic_op op) + { + switch (op) + { + case rsx::logic_op::logic_clear: return GL_CLEAR; + case rsx::logic_op::logic_and: return GL_AND; + case rsx::logic_op::logic_and_reverse: return GL_AND_REVERSE; + case rsx::logic_op::logic_copy: return GL_COPY; + case rsx::logic_op::logic_and_inverted: return GL_AND_INVERTED; + case rsx::logic_op::logic_noop: return GL_NOOP; + case rsx::logic_op::logic_xor: return GL_XOR; + case rsx::logic_op::logic_or : return GL_OR; + case rsx::logic_op::logic_nor: return GL_NOR; + case rsx::logic_op::logic_equiv: return GL_EQUIV; + case rsx::logic_op::logic_invert: return GL_INVERT; + case rsx::logic_op::logic_or_reverse: return GL_OR_REVERSE; + case rsx::logic_op::logic_copy_inverted: return GL_COPY_INVERTED; + case rsx::logic_op::logic_or_inverted: return GL_OR_INVERTED; + case rsx::logic_op::logic_nand: return GL_NAND; + case rsx::logic_op::logic_set: return GL_SET; + } + throw; + } + + GLenum front_face(rsx::front_face op) + { + switch (op) + { + case rsx::front_face::cw: return GL_CW; + case rsx::front_face::ccw: return GL_CCW; + } + throw; + } + + GLenum cull_face(rsx::cull_face op) + { + switch (op) + { + case rsx::cull_face::front: return GL_FRONT; + case rsx::cull_face::back: return GL_BACK; + case rsx::cull_face::front_and_back: return GL_FRONT_AND_BACK; + } + throw; + } +} + void GLGSRender::begin() { rsx::thread::begin(); @@ -79,127 +198,110 @@ void GLGSRender::begin() std::chrono::time_point then = std::chrono::system_clock::now(); - u32 color_mask = rsx::method_registers[NV4097_SET_COLOR_MASK]; - bool color_mask_b = !!(color_mask & 0xff); - bool color_mask_g = !!((color_mask >> 8) & 0xff); - bool color_mask_r = !!((color_mask >> 16) & 0xff); - bool color_mask_a = !!((color_mask >> 24) & 0xff); + bool color_mask_b = rsx::method_registers.color_mask_b(); + bool color_mask_g = rsx::method_registers.color_mask_g(); + bool color_mask_r = rsx::method_registers.color_mask_r(); + bool color_mask_a = rsx::method_registers.color_mask_a(); __glcheck glColorMask(color_mask_r, color_mask_g, color_mask_b, color_mask_a); - __glcheck glDepthMask(rsx::method_registers[NV4097_SET_DEPTH_MASK]); - __glcheck glStencilMask(rsx::method_registers[NV4097_SET_STENCIL_MASK]); + __glcheck glDepthMask(rsx::method_registers.depth_write_enabled()); + __glcheck glStencilMask(rsx::method_registers.stencil_mask()); - if (__glcheck enable(rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE], GL_DEPTH_TEST)) + if (__glcheck enable(rsx::method_registers.depth_test_enabled(), GL_DEPTH_TEST)) { - __glcheck glDepthFunc(rsx::method_registers[NV4097_SET_DEPTH_FUNC]); - __glcheck glDepthMask(rsx::method_registers[NV4097_SET_DEPTH_MASK]); + __glcheck glDepthFunc(comparaison_op(rsx::method_registers.depth_func())); + __glcheck glDepthMask(rsx::method_registers.depth_write_enabled()); } - if (glDepthBoundsEXT && (__glcheck enable(rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE], GL_DEPTH_BOUNDS_TEST_EXT))) + if (glDepthBoundsEXT && (__glcheck enable(rsx::method_registers.depth_bounds_test_enabled(), GL_DEPTH_BOUNDS_TEST_EXT))) { - __glcheck glDepthBoundsEXT((f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MIN], (f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MAX]); + __glcheck glDepthBoundsEXT(rsx::method_registers.depth_bounds_min(), rsx::method_registers.depth_bounds_max()); } - __glcheck glDepthRange((f32&)rsx::method_registers[NV4097_SET_CLIP_MIN], (f32&)rsx::method_registers[NV4097_SET_CLIP_MAX]); - __glcheck enable(rsx::method_registers[NV4097_SET_DITHER_ENABLE], GL_DITHER); + __glcheck glDepthRange(rsx::method_registers.clip_min(), rsx::method_registers.clip_max()); + __glcheck enable(rsx::method_registers.dither_enabled(), GL_DITHER); - if (__glcheck enable(rsx::method_registers[NV4097_SET_BLEND_ENABLE], GL_BLEND)) + if (__glcheck enable(rsx::method_registers.blend_enabled(), GL_BLEND)) { - u32 sfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR]; - u32 dfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR]; - u16 sfactor_rgb = sfactor; - u16 sfactor_a = sfactor >> 16; - u16 dfactor_rgb = dfactor; - u16 dfactor_a = dfactor >> 16; - - __glcheck glBlendFuncSeparate(sfactor_rgb, dfactor_rgb, sfactor_a, dfactor_a); + __glcheck glBlendFuncSeparate(blend_factor(rsx::method_registers.blend_func_sfactor_rgb()), + blend_factor(rsx::method_registers.blend_func_dfactor_rgb()), + blend_factor(rsx::method_registers.blend_func_sfactor_a()), + blend_factor(rsx::method_registers.blend_func_dfactor_a())); if (m_surface.color_format == rsx::surface_color_format::w16z16y16x16) //TODO: check another color formats { - u32 blend_color = rsx::method_registers[NV4097_SET_BLEND_COLOR]; - u32 blend_color2 = rsx::method_registers[NV4097_SET_BLEND_COLOR2]; - - u16 blend_color_r = blend_color; - u16 blend_color_g = blend_color >> 16; - u16 blend_color_b = blend_color2; - u16 blend_color_a = blend_color2 >> 16; + u16 blend_color_r = rsx::method_registers.blend_color_16b_r(); + u16 blend_color_g = rsx::method_registers.blend_color_16b_g(); + u16 blend_color_b = rsx::method_registers.blend_color_16b_b(); + u16 blend_color_a = rsx::method_registers.blend_color_16b_a(); __glcheck glBlendColor(blend_color_r / 65535.f, blend_color_g / 65535.f, blend_color_b / 65535.f, blend_color_a / 65535.f); } else { - u32 blend_color = rsx::method_registers[NV4097_SET_BLEND_COLOR]; - u8 blend_color_r = blend_color; - u8 blend_color_g = blend_color >> 8; - u8 blend_color_b = blend_color >> 16; - u8 blend_color_a = blend_color >> 24; + u8 blend_color_r = rsx::method_registers.blend_color_8b_r(); + u8 blend_color_g = rsx::method_registers.blend_color_8b_g(); + u8 blend_color_b = rsx::method_registers.blend_color_8b_b(); + u8 blend_color_a = rsx::method_registers.blend_color_8b_a(); __glcheck glBlendColor(blend_color_r / 255.f, blend_color_g / 255.f, blend_color_b / 255.f, blend_color_a / 255.f); } - u32 equation = rsx::method_registers[NV4097_SET_BLEND_EQUATION]; - u16 equation_rgb = equation; - u16 equation_a = equation >> 16; - - __glcheck glBlendEquationSeparate(equation_rgb, equation_a); + __glcheck glBlendEquationSeparate(blend_equation(rsx::method_registers.blend_equation_rgb()), + blend_equation(rsx::method_registers.blend_equation_a())); } - if (__glcheck enable(rsx::method_registers[NV4097_SET_STENCIL_TEST_ENABLE], GL_STENCIL_TEST)) + if (__glcheck enable(rsx::method_registers.stencil_test_enabled(), GL_STENCIL_TEST)) { - __glcheck glStencilFunc(rsx::method_registers[NV4097_SET_STENCIL_FUNC], rsx::method_registers[NV4097_SET_STENCIL_FUNC_REF], - rsx::method_registers[NV4097_SET_STENCIL_FUNC_MASK]); - __glcheck glStencilOp(rsx::method_registers[NV4097_SET_STENCIL_OP_FAIL], rsx::method_registers[NV4097_SET_STENCIL_OP_ZFAIL], - rsx::method_registers[NV4097_SET_STENCIL_OP_ZPASS]); + __glcheck glStencilFunc(comparaison_op(rsx::method_registers.stencil_func()), rsx::method_registers.stencil_func_ref(), + rsx::method_registers.stencil_func_mask()); + __glcheck glStencilOp(stencil_op(rsx::method_registers.stencil_op_fail()), stencil_op(rsx::method_registers.stencil_op_zfail()), + stencil_op(rsx::method_registers.stencil_op_zpass())); - if (rsx::method_registers[NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE]) - { - __glcheck glStencilMaskSeparate(GL_BACK, rsx::method_registers[NV4097_SET_BACK_STENCIL_MASK]); - __glcheck glStencilFuncSeparate(GL_BACK, rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC], - rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC_REF], rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC_MASK]); - __glcheck glStencilOpSeparate(GL_BACK, rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_FAIL], - rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZFAIL], rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZPASS]); + if (rsx::method_registers.two_sided_stencil_test_enabled()) { + __glcheck glStencilMaskSeparate(GL_BACK, rsx::method_registers.back_stencil_mask()); + __glcheck glStencilFuncSeparate(GL_BACK, comparaison_op(rsx::method_registers.back_stencil_func()), + rsx::method_registers.back_stencil_func_ref(), rsx::method_registers.back_stencil_func_mask()); + __glcheck glStencilOpSeparate(GL_BACK, stencil_op(rsx::method_registers.back_stencil_op_fail()), + stencil_op(rsx::method_registers.back_stencil_op_zfail()), stencil_op(rsx::method_registers.back_stencil_op_zpass())); } } - if (u32 blend_mrt = rsx::method_registers[NV4097_SET_BLEND_ENABLE_MRT]) - { - __glcheck enable(blend_mrt & 2, GL_BLEND, 1); - __glcheck enable(blend_mrt & 4, GL_BLEND, 2); - __glcheck enable(blend_mrt & 8, GL_BLEND, 3); - } + __glcheck enable(rsx::method_registers.blend_enabled_surface_1(), GL_BLEND, 1); + __glcheck enable(rsx::method_registers.blend_enabled_surface_2(), GL_BLEND, 2); + __glcheck enable(rsx::method_registers.blend_enabled_surface_3(), GL_BLEND, 3); - if (__glcheck enable(rsx::method_registers[NV4097_SET_LOGIC_OP_ENABLE], GL_COLOR_LOGIC_OP)) + if (__glcheck enable(rsx::method_registers.logic_op_enabled(), GL_COLOR_LOGIC_OP)) { - __glcheck glLogicOp(rsx::method_registers[NV4097_SET_LOGIC_OP]); + __glcheck glLogicOp(logic_op(rsx::method_registers.logic_operation())); } - u32 line_width = rsx::method_registers[NV4097_SET_LINE_WIDTH]; - __glcheck glLineWidth((line_width >> 3) + (line_width & 7) / 8.f); - __glcheck enable(rsx::method_registers[NV4097_SET_LINE_SMOOTH_ENABLE], GL_LINE_SMOOTH); + __glcheck glLineWidth(rsx::method_registers.line_width()); + __glcheck enable(rsx::method_registers.line_smooth_enabled(), GL_LINE_SMOOTH); //TODO //NV4097_SET_ANISO_SPREAD - __glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_POINT_ENABLE], GL_POLYGON_OFFSET_POINT); - __glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_LINE_ENABLE], GL_POLYGON_OFFSET_LINE); - __glcheck enable(rsx::method_registers[NV4097_SET_POLY_OFFSET_FILL_ENABLE], GL_POLYGON_OFFSET_FILL); + __glcheck enable(rsx::method_registers.poly_offset_point_enabled(), GL_POLYGON_OFFSET_POINT); + __glcheck enable(rsx::method_registers.poly_offset_line_enabled(), GL_POLYGON_OFFSET_LINE); + __glcheck enable(rsx::method_registers.poly_offset_fill_enabled(), GL_POLYGON_OFFSET_FILL); - __glcheck glPolygonOffset((f32&)rsx::method_registers[NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR], - (f32&)rsx::method_registers[NV4097_SET_POLYGON_OFFSET_BIAS]); + __glcheck glPolygonOffset(rsx::method_registers.poly_offset_scale(), + rsx::method_registers.poly_offset_bias()); //NV4097_SET_SPECULAR_ENABLE //NV4097_SET_TWO_SIDE_LIGHT_EN //NV4097_SET_FLAT_SHADE_OP //NV4097_SET_EDGE_FLAG - if (__glcheck enable(rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE], GL_CULL_FACE)) + if (__glcheck enable(rsx::method_registers.cull_face_enabled(), GL_CULL_FACE)) { - __glcheck glCullFace(rsx::method_registers[NV4097_SET_CULL_FACE]); + __glcheck glCullFace(cull_face(rsx::method_registers.cull_face_mode())); } - __glcheck glFrontFace(get_front_face_ccw(rsx::method_registers[NV4097_SET_FRONT_FACE] ^ 1)); + __glcheck glFrontFace(front_face(rsx::method_registers.front_face_mode())); - __glcheck enable(rsx::method_registers[NV4097_SET_POLY_SMOOTH_ENABLE], GL_POLYGON_SMOOTH); + __glcheck enable(rsx::method_registers.poly_smooth_enabled(), GL_POLYGON_SMOOTH); //NV4097_SET_COLOR_KEY_COLOR //NV4097_SET_SHADER_CONTROL @@ -207,9 +309,9 @@ void GLGSRender::begin() //NV4097_SET_ANTI_ALIASING_CONTROL //NV4097_SET_CLIP_ID_TEST_ENABLE - if (__glcheck enable(rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE], GL_PRIMITIVE_RESTART)) + if (__glcheck enable(rsx::method_registers.restart_index_enabled(), GL_PRIMITIVE_RESTART)) { - __glcheck glPrimitiveRestartIndex(rsx::method_registers[NV4097_SET_RESTART_INDEX]); + __glcheck glPrimitiveRestartIndex(rsx::method_registers.restart_index()); } std::chrono::time_point now = std::chrono::system_clock::now(); @@ -252,15 +354,14 @@ void GLGSRender::end() return; } - u32 clip_plane_control = rsx::method_registers[NV4097_SET_USER_CLIP_PLANE_CONTROL]; - u8 clip_plane_0 = clip_plane_control & 0xf; - u8 clip_plane_1 = (clip_plane_control >> 4) & 0xf; - u8 clip_plane_2 = (clip_plane_control >> 8) & 0xf; - u8 clip_plane_3 = (clip_plane_control >> 12) & 0xf; - u8 clip_plane_4 = (clip_plane_control >> 16) & 0xf; - u8 clip_plane_5 = (clip_plane_control >> 20) & 0xf; + rsx::user_clip_plane_op clip_plane_0 = rsx::method_registers.clip_plane_0_enabled(); + rsx::user_clip_plane_op clip_plane_1 = rsx::method_registers.clip_plane_1_enabled(); + rsx::user_clip_plane_op clip_plane_2 = rsx::method_registers.clip_plane_2_enabled(); + rsx::user_clip_plane_op clip_plane_3 = rsx::method_registers.clip_plane_3_enabled(); + rsx::user_clip_plane_op clip_plane_4 = rsx::method_registers.clip_plane_4_enabled(); + rsx::user_clip_plane_op clip_plane_5 = rsx::method_registers.clip_plane_5_enabled(); - auto set_clip_plane_control = [&](int index, u8 control) + auto set_clip_plane_control = [&](int index, rsx::user_clip_plane_op control) { int value = 0; int location; @@ -271,15 +372,15 @@ void GLGSRender::end() default: LOG_ERROR(RSX, "bad clip plane control (0x%x)", control); - case CELL_GCM_USER_CLIP_PLANE_DISABLE: + case rsx::user_clip_plane_op::disable: value = 0; break; - case CELL_GCM_USER_CLIP_PLANE_ENABLE_GE: + case rsx::user_clip_plane_op::greather_or_equal: value = 1; break; - case CELL_GCM_USER_CLIP_PLANE_ENABLE_LT: + case rsx::user_clip_plane_op::less_than: value = -1; break; } @@ -307,7 +408,7 @@ void GLGSRender::end() int location; if (m_program->uniforms.has_location("ftexture" + std::to_string(i), &location)) { - if (!textures[i].enabled()) + if (!rsx::method_registers.fragment_textures[i].enabled()) { glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, 0); @@ -316,18 +417,18 @@ void GLGSRender::end() continue; } - m_gl_textures[i].set_target(get_gl_target_for_texture(textures[i])); + m_gl_textures[i].set_target(get_gl_target_for_texture(rsx::method_registers.fragment_textures[i])); - __glcheck m_gl_texture_cache.upload_texture(i, textures[i], m_gl_textures[i], m_rtts); + __glcheck m_gl_texture_cache.upload_texture(i, rsx::method_registers.fragment_textures[i], m_gl_textures[i], m_rtts); __glcheck glProgramUniform1i(m_program->id(), location, i); if (m_program->uniforms.has_location("ftexture" + std::to_string(i) + "_cm", &location)) { - if (textures[i].format() & CELL_GCM_TEXTURE_UN) + if (rsx::method_registers.fragment_textures[i].format() & CELL_GCM_TEXTURE_UN) { - u32 width = std::max(textures[i].width(), 1); - u32 height = std::max(textures[i].height(), 1); - u32 depth = std::max(textures[i].depth(), 1); + u32 width = std::max(rsx::method_registers.fragment_textures[i].width(), 1); + u32 height = std::max(rsx::method_registers.fragment_textures[i].height(), 1); + u32 depth = std::max(rsx::method_registers.fragment_textures[i].depth(), 1); glProgramUniform4f(m_program->id(), location, 1.f / width, 1.f / height, 1.f / depth, 1.0f); } @@ -340,7 +441,7 @@ void GLGSRender::end() int location; if (m_program->uniforms.has_location("vtexture" + std::to_string(i), &location)) { - if (!textures[i].enabled()) + if (!rsx::method_registers.fragment_textures[i].enabled()) { glActiveTexture(GL_TEXTURE0 + i); glBindTexture(GL_TEXTURE_2D, 0); @@ -349,18 +450,18 @@ void GLGSRender::end() continue; } - m_gl_vertex_textures[i].set_target(get_gl_target_for_texture(vertex_textures[i])); + m_gl_vertex_textures[i].set_target(get_gl_target_for_texture(rsx::method_registers.vertex_textures[i])); - __glcheck m_gl_texture_cache.upload_texture(i, vertex_textures[i], m_gl_vertex_textures[i], m_rtts); + __glcheck m_gl_texture_cache.upload_texture(i, rsx::method_registers.vertex_textures[i], m_gl_vertex_textures[i], m_rtts); __glcheck glProgramUniform1i(m_program->id(), location, i); if (m_program->uniforms.has_location("vtexture" + std::to_string(i) + "_cm", &location)) { - if (textures[i].format() & CELL_GCM_TEXTURE_UN) + if (rsx::method_registers.fragment_textures[i].format() & CELL_GCM_TEXTURE_UN) { - u32 width = std::max(textures[i].width(), 1); - u32 height = std::max(textures[i].height(), 1); - u32 depth = std::max(textures[i].depth(), 1); + u32 width = std::max(rsx::method_registers.fragment_textures[i].width(), 1); + u32 height = std::max(rsx::method_registers.fragment_textures[i].height(), 1); + u32 depth = std::max(rsx::method_registers.fragment_textures[i].depth(), 1); glProgramUniform4f(m_program->id(), location, 1.f / width, 1.f / height, 1.f / depth, 1.0f); } @@ -381,7 +482,7 @@ void GLGSRender::end() if (draw_command == rsx::draw_command::indexed) { - rsx::index_array_type indexed_type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4); + rsx::index_array_type indexed_type = rsx::method_registers.index_type(); if (indexed_type == rsx::index_array_type::u32) { @@ -415,24 +516,17 @@ void GLGSRender::end() void GLGSRender::set_viewport() { - u32 viewport_horizontal = rsx::method_registers[NV4097_SET_VIEWPORT_HORIZONTAL]; - u32 viewport_vertical = rsx::method_registers[NV4097_SET_VIEWPORT_VERTICAL]; + u16 viewport_x = rsx::method_registers.viewport_origin_x(); + u16 viewport_y = rsx::method_registers.viewport_origin_y(); + u16 viewport_w = rsx::method_registers.viewport_width(); + u16 viewport_h = rsx::method_registers.viewport_height(); - u16 viewport_x = viewport_horizontal & 0xffff; - u16 viewport_y = viewport_vertical & 0xffff; - u16 viewport_w = viewport_horizontal >> 16; - u16 viewport_h = viewport_vertical >> 16; + u16 scissor_x = rsx::method_registers.scissor_origin_x(); + u16 scissor_w = rsx::method_registers.scissor_width(); + u16 scissor_y = rsx::method_registers.scissor_origin_y(); + u16 scissor_h = rsx::method_registers.scissor_height(); - u32 scissor_horizontal = rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL]; - u32 scissor_vertical = rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL]; - u16 scissor_x = scissor_horizontal; - u16 scissor_w = scissor_horizontal >> 16; - u16 scissor_y = scissor_vertical; - u16 scissor_h = scissor_vertical >> 16; - - u32 shader_window = rsx::method_registers[NV4097_SET_SHADER_WINDOW]; - - rsx::window_origin shader_window_origin = rsx::to_window_origin((shader_window >> 12) & 0xf); + rsx::window_origin shader_window_origin = rsx::method_registers.shader_window_origin(); if (shader_window_origin == rsx::window_origin::bottom) { @@ -441,7 +535,7 @@ void GLGSRender::set_viewport() } else { - u16 shader_window_height = shader_window & 0xfff; + u16 shader_window_height = rsx::method_registers.shader_window_height(); __glcheck glViewport(viewport_x, shader_window_height - viewport_y - viewport_h + 1, viewport_w, viewport_h); __glcheck glScissor(scissor_x, shader_window_height - scissor_y - scissor_h + 1, scissor_w, scissor_h); @@ -519,10 +613,7 @@ void GLGSRender::on_exit() void nv4097_clear_surface(u32 arg, GLGSRender* renderer) { //LOG_NOTICE(Log::RSX, "nv4097_clear_surface(0x%x)", arg); - if (!rsx::method_registers[NV4097_SET_SURFACE_FORMAT]) - { - return; - } + if (rsx::method_registers.surface_color_target() == rsx::surface_target::none) return; if ((arg & 0xf3) == 0) { @@ -543,13 +634,13 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer) GLbitfield mask = 0; - rsx::surface_depth_format surface_depth_format = rsx::to_surface_depth_format((rsx::method_registers[NV4097_SET_SURFACE_FORMAT] >> 5) & 0x7); + rsx::surface_depth_format surface_depth_format = rsx::method_registers.surface_depth_fmt(); if (arg & 0x1) { u32 max_depth_value = get_max_depth_value(surface_depth_format); - u32 clear_depth = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] >> 8; + u32 clear_depth = rsx::method_registers.z_clear_value(); glDepthMask(GL_TRUE); glClearDepth(double(clear_depth) / max_depth_value); @@ -558,9 +649,9 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer) if (surface_depth_format == rsx::surface_depth_format::z24s8 && (arg & 0x2)) { - u8 clear_stencil = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] & 0xff; + u8 clear_stencil = rsx::method_registers.stencil_clear_value(); - __glcheck glStencilMask(rsx::method_registers[NV4097_SET_STENCIL_MASK]); + __glcheck glStencilMask(rsx::method_registers.stencil_mask()); glClearStencil(clear_stencil); mask |= GLenum(gl::buffers::stencil); @@ -568,11 +659,10 @@ void nv4097_clear_surface(u32 arg, GLGSRender* renderer) if (arg & 0xf0) { - u32 clear_color = rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]; - u8 clear_a = clear_color >> 24; - u8 clear_r = clear_color >> 16; - u8 clear_g = clear_color >> 8; - u8 clear_b = clear_color; + u8 clear_a = rsx::method_registers.clear_color_a(); + u8 clear_r = rsx::method_registers.clear_color_r(); + u8 clear_g = rsx::method_registers.clear_color_g(); + u8 clear_b = rsx::method_registers.clear_color_b(); glColorMask(((arg & 0x20) ? 1 : 0), ((arg & 0x40) ? 1 : 0), ((arg & 0x80) ? 1 : 0), ((arg & 0x10) ? 1 : 0)); glClearColor(clear_r / 255.f, clear_g / 255.f, clear_b / 255.f, clear_a / 255.f); @@ -638,18 +728,13 @@ static void fill_matrix_buffer(glsl_matrix_buffer *buffer) rsx::fill_viewport_matrix(buffer->viewport_matrix, true); rsx::fill_window_matrix(buffer->window_matrix, true); - u32 viewport_horizontal = rsx::method_registers[NV4097_SET_VIEWPORT_HORIZONTAL]; - u32 viewport_vertical = rsx::method_registers[NV4097_SET_VIEWPORT_VERTICAL]; + f32 viewport_x = rsx::method_registers.viewport_origin_x(); + f32 viewport_y = rsx::method_registers.viewport_origin_y(); + f32 viewport_w = rsx::method_registers.viewport_width(); + f32 viewport_h = rsx::method_registers.viewport_height(); - f32 viewport_x = f32(viewport_horizontal & 0xffff); - f32 viewport_y = f32(viewport_vertical & 0xffff); - f32 viewport_w = f32(viewport_horizontal >> 16); - f32 viewport_h = f32(viewport_vertical >> 16); - - u32 shader_window = rsx::method_registers[NV4097_SET_SHADER_WINDOW]; - - rsx::window_origin shader_window_origin = rsx::to_window_origin((shader_window >> 12) & 0xf); - u16 shader_window_height = shader_window & 0xfff; + rsx::window_origin shader_window_origin = rsx::method_registers.shader_window_origin(); + u16 shader_window_height = rsx::method_registers.shader_window_height(); f32 left = viewport_x; f32 right = viewport_x + viewport_w; @@ -683,10 +768,11 @@ static void fill_matrix_buffer(glsl_matrix_buffer *buffer) static void fill_fragment_state_buffer(glsl_fragment_state_buffer *buffer) { - std::memcpy(&buffer->fog_param0, rsx::method_registers + NV4097_SET_FOG_PARAMS, sizeof(float) * 2); + const float fog_params[2] = { rsx::method_registers.fog_params_0(), rsx::method_registers.fog_params_1() }; + std::memcpy(&buffer->fog_param0, fog_params, sizeof(float) * 2); - buffer->alpha_test = rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE]; - buffer->alpha_ref = rsx::method_registers[NV4097_SET_ALPHA_REF] / 255.f; + buffer->alpha_test = rsx::method_registers.alpha_test_enabled(); + buffer->alpha_ref = rsx::method_registers.alpha_ref() / 255.f; } bool GLGSRender::load_program() diff --git a/rpcs3/Emu/RSX/GL/gl_render_targets.cpp b/rpcs3/Emu/RSX/GL/gl_render_targets.cpp index 8d568f0b17..9ce144ace4 100644 --- a/rpcs3/Emu/RSX/GL/gl_render_targets.cpp +++ b/rpcs3/Emu/RSX/GL/gl_render_targets.cpp @@ -78,10 +78,8 @@ u8 rsx::internals::get_pixel_size(rsx::surface_depth_format format) void GLGSRender::init_buffers(bool skip_reading) { - u32 surface_format = rsx::method_registers[NV4097_SET_SURFACE_FORMAT]; - - u32 clip_horizontal = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL]; - u32 clip_vertical = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL]; + u16 clip_horizontal = rsx::method_registers.surface_clip_width(); + u16 clip_vertical = rsx::method_registers.surface_clip_height(); set_viewport(); @@ -97,8 +95,8 @@ void GLGSRender::init_buffers(bool skip_reading) LOG_NOTICE(RSX, "render to -> 0x%x", get_color_surface_addresses()[0]); } - m_rtts.prepare_render_target(nullptr, surface_format, clip_horizontal, clip_vertical, - rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]), + m_rtts.prepare_render_target(nullptr, rsx::method_registers.surface_color(), rsx::method_registers.surface_depth_fmt(), clip_horizontal, clip_vertical, + rsx::method_registers.surface_color_target(), get_color_surface_addresses(), get_zeta_surface_address()); draw_fbo.recreate(); @@ -119,7 +117,7 @@ void GLGSRender::init_buffers(bool skip_reading) __glcheck draw_fbo.check(); //HACK: read_buffer shouldn't be there - switch (rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) + switch (rsx::method_registers.surface_color_target()) { case rsx::surface_target::none: break; @@ -152,20 +150,49 @@ void GLGSRender::init_buffers(bool skip_reading) std::array, 4> GLGSRender::copy_render_targets_to_memory() { - int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; - int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; - rsx::surface_info surface = {}; - surface.unpack(rsx::method_registers[NV4097_SET_SURFACE_FORMAT]); - return m_rtts.get_render_targets_data(surface.color_format, clip_w, clip_h); + int clip_w = rsx::method_registers.surface_clip_width(); + int clip_h = rsx::method_registers.surface_clip_height(); + return m_rtts.get_render_targets_data(rsx::method_registers.surface_color(), clip_w, clip_h); } std::array, 2> GLGSRender::copy_depth_stencil_buffer_to_memory() { - int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; - int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; - rsx::surface_info surface = {}; - surface.unpack(rsx::method_registers[NV4097_SET_SURFACE_FORMAT]); - return m_rtts.get_depth_stencil_data(surface.depth_format, clip_w, clip_h); + int clip_w = rsx::method_registers.surface_clip_width(); + int clip_h = rsx::method_registers.surface_clip_height(); + return m_rtts.get_depth_stencil_data(rsx::method_registers.surface_depth_fmt(), clip_w, clip_h); +} + +namespace +{ + std::array get_offsets() + { + return{ + rsx::method_registers.surface_a_offset(), + rsx::method_registers.surface_b_offset(), + rsx::method_registers.surface_c_offset(), + rsx::method_registers.surface_d_offset(), + }; + } + + std::array get_locations() + { + return{ + rsx::method_registers.surface_a_dma(), + rsx::method_registers.surface_b_dma(), + rsx::method_registers.surface_c_dma(), + rsx::method_registers.surface_d_dma(), + }; + } + + std::array get_pitchs() + { + return{ + rsx::method_registers.surface_a_pitch(), + rsx::method_registers.surface_b_pitch(), + rsx::method_registers.surface_c_pitch(), + rsx::method_registers.surface_d_pitch(), + }; + } } void GLGSRender::read_buffers() @@ -181,14 +208,18 @@ void GLGSRender::read_buffers() auto read_color_buffers = [&](int index, int count) { - u32 width = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; - u32 height = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; + u32 width = rsx::method_registers.surface_clip_width(); + u32 height = rsx::method_registers.surface_clip_height(); + + const std::array offsets = get_offsets(); + const std::array locations = get_locations(); + const std::array pitchs = get_pitchs(); for (int i = index; i < index + count; ++i) { - u32 offset = rsx::method_registers[rsx::internals::mr_color_offset[i]]; - u32 location = rsx::method_registers[rsx::internals::mr_color_dma[i]]; - u32 pitch = rsx::method_registers[rsx::internals::mr_color_pitch[i]]; + u32 offset = offsets[i]; + u32 location = locations[i]; + u32 pitch = pitchs[i]; if (pitch <= 64) continue; @@ -219,7 +250,7 @@ void GLGSRender::read_buffers() } }; - switch (rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) + switch (rsx::method_registers.surface_color_target()) { case rsx::surface_target::none: break; @@ -249,12 +280,12 @@ void GLGSRender::read_buffers() if (g_cfg_rsx_read_depth_buffer) { //TODO: use pitch - u32 pitch = rsx::method_registers[NV4097_SET_SURFACE_PITCH_Z]; + u32 pitch = rsx::method_registers.surface_z_pitch(); if (pitch <= 64) return; - u32 depth_address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]); + u32 depth_address = rsx::get_address(rsx::method_registers.surface_z_offset(), rsx::method_registers.surface_z_dma()); bool in_cache = m_gl_texture_cache.explicit_writeback((*std::get<1>(m_rtts.m_bound_depth_stencil)), depth_address, pitch); if (in_cache) @@ -269,7 +300,7 @@ void GLGSRender::read_buffers() __glcheck pbo_depth.create(m_surface.width * m_surface.height * pixel_size); __glcheck pbo_depth.map([&](GLubyte* pixels) { - u32 depth_address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]); + u32 depth_address = rsx::get_address(rsx::method_registers.surface_z_offset(), rsx::method_registers.surface_z_dma()); if (m_surface.depth_format == rsx::surface_depth_format::z16) { @@ -309,14 +340,18 @@ void GLGSRender::write_buffers() auto write_color_buffers = [&](int index, int count) { - u32 width = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; - u32 height = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; + u32 width = rsx::method_registers.surface_clip_width(); + u32 height = rsx::method_registers.surface_clip_height(); + + std::array offsets = get_offsets(); + const std::array locations = get_locations(); + const std::array pitchs = get_pitchs(); for (int i = index; i < index + count; ++i) { - u32 offset = rsx::method_registers[rsx::internals::mr_color_offset[i]]; - u32 location = rsx::method_registers[rsx::internals::mr_color_dma[i]]; - u32 pitch = rsx::method_registers[rsx::internals::mr_color_pitch[i]]; + u32 offset = offsets[i]; + u32 location = locations[i]; + u32 pitch = pitchs[i]; if (pitch <= 64) continue; @@ -334,7 +369,7 @@ void GLGSRender::write_buffers() } }; - switch (rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])) + switch (rsx::method_registers.surface_color_target()) { case rsx::surface_target::none: break; @@ -364,13 +399,13 @@ void GLGSRender::write_buffers() if (g_cfg_rsx_write_depth_buffer) { //TODO: use pitch - u32 pitch = rsx::method_registers[NV4097_SET_SURFACE_PITCH_Z]; + u32 pitch = rsx::method_registers.surface_z_pitch(); if (pitch <= 64) return; auto depth_format = rsx::internals::surface_depth_format_to_gl(m_surface.depth_format); - u32 depth_address = rsx::get_address(rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET], rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]); + u32 depth_address = rsx::get_address(rsx::method_registers.surface_z_offset(), rsx::method_registers.surface_z_dma()); u32 range = std::get<1>(m_rtts.m_bound_depth_stencil)->width() * std::get<1>(m_rtts.m_bound_depth_stencil)->height() * 2; if (m_surface.depth_format != rsx::surface_depth_format::z16) range *= 2; diff --git a/rpcs3/Emu/RSX/GL/gl_render_targets.h b/rpcs3/Emu/RSX/GL/gl_render_targets.h index 6de4e4ae85..4fb05d7c13 100644 --- a/rpcs3/Emu/RSX/GL/gl_render_targets.h +++ b/rpcs3/Emu/RSX/GL/gl_render_targets.h @@ -42,30 +42,6 @@ namespace rsx color_format surface_color_format_to_gl(rsx::surface_color_format color_format); depth_format surface_depth_format_to_gl(rsx::surface_depth_format depth_format); u8 get_pixel_size(rsx::surface_depth_format format); - - const u32 mr_color_offset[rsx::limits::color_buffers_count] = - { - NV4097_SET_SURFACE_COLOR_AOFFSET, - NV4097_SET_SURFACE_COLOR_BOFFSET, - NV4097_SET_SURFACE_COLOR_COFFSET, - NV4097_SET_SURFACE_COLOR_DOFFSET - }; - - const u32 mr_color_dma[rsx::limits::color_buffers_count] = - { - NV4097_SET_CONTEXT_DMA_COLOR_A, - NV4097_SET_CONTEXT_DMA_COLOR_B, - NV4097_SET_CONTEXT_DMA_COLOR_C, - NV4097_SET_CONTEXT_DMA_COLOR_D - }; - - const u32 mr_color_pitch[rsx::limits::color_buffers_count] = - { - NV4097_SET_SURFACE_PITCH_A, - NV4097_SET_SURFACE_PITCH_B, - NV4097_SET_SURFACE_PITCH_C, - NV4097_SET_SURFACE_PITCH_D - }; } } diff --git a/rpcs3/Emu/RSX/GL/vertex_buffer.cpp b/rpcs3/Emu/RSX/GL/vertex_buffer.cpp index eaa958469a..5da0c2d4e9 100644 --- a/rpcs3/Emu/RSX/GL/vertex_buffer.cpp +++ b/rpcs3/Emu/RSX/GL/vertex_buffer.cpp @@ -164,7 +164,7 @@ u32 GLGSRender::set_vertex_buffer() std::chrono::time_point then = std::chrono::system_clock::now(); - u32 input_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK]; + u32 input_mask = rsx::method_registers.vertex_attrib_input_mask(); u32 min_index = 0, max_index = 0; u32 max_vertex_attrib_size = 0; u32 offset_in_index_buffer = 0; @@ -176,7 +176,7 @@ u32 GLGSRender::set_vertex_buffer() for (u8 index = 0; index < rsx::limits::vertex_count; ++index) { - if (vertex_arrays_info[index].size || register_vertex_info[index].size) + if (rsx::method_registers.vertex_arrays_info[index].size || rsx::method_registers.register_vertex_info[index].size) { max_vertex_attrib_size += 16; } @@ -184,7 +184,7 @@ u32 GLGSRender::set_vertex_buffer() if (draw_command == rsx::draw_command::indexed) { - rsx::index_array_type type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4); + rsx::index_array_type type = rsx::method_registers.index_type(); u32 type_size = gsl::narrow(get_index_type_size(type)); for (const auto& first_count : first_count_commands) { @@ -212,7 +212,7 @@ u32 GLGSRender::set_vertex_buffer() for (u32 i = 0; i < rsx::limits::vertex_count; ++i) { - const auto &info = vertex_arrays_info[i]; + const auto &info = rsx::method_registers.vertex_arrays_info[i]; if (!info.size) continue; offsets[i] = stride; @@ -224,7 +224,7 @@ u32 GLGSRender::set_vertex_buffer() for (int index = 0; index < rsx::limits::vertex_count; ++index) { - auto &vertex_info = vertex_arrays_info[index]; + auto &vertex_info = rsx::method_registers.vertex_arrays_info[index]; int location; if (!m_program->uniforms.has_location(rsx::vertex_program::input_attrib_names[index] + "_buffer", &location)) @@ -307,9 +307,9 @@ u32 GLGSRender::set_vertex_buffer() continue; } - if (vertex_arrays_info[index].size > 0) + if (rsx::method_registers.vertex_arrays_info[index].size > 0) { - auto &vertex_info = vertex_arrays_info[index]; + auto &vertex_info = rsx::method_registers.vertex_arrays_info[index]; // Fill vertex_array u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size); @@ -322,8 +322,8 @@ u32 GLGSRender::set_vertex_buffer() u32 buffer_offset = 0; // Get source pointer - u32 base_offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET]; - u32 offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + index]; + u32 base_offset = rsx::method_registers.vertex_data_base_offset(); + u32 offset = rsx::method_registers.vertex_arrays_info[index].offset(); u32 address = base_offset + rsx::get_address(offset & 0x7fffffff, offset >> 31); const gsl::byte *src_ptr = gsl::narrow_cast(vm::base(address)); @@ -361,10 +361,10 @@ u32 GLGSRender::set_vertex_buffer() //Link texture to uniform m_program->uniforms.texture(location, index + texture_index_offset, texture); } - else if (register_vertex_info[index].size > 0) + else if (rsx::method_registers.register_vertex_info[index].size > 0) { - auto &vertex_data = register_vertex_data[index]; - auto &vertex_info = register_vertex_info[index]; + auto &vertex_data = rsx::method_registers.register_vertex_data[index]; + auto &vertex_info = rsx::method_registers.register_vertex_info[index]; switch (vertex_info.type) { diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index 2517ebd75d..71c65fd111 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -6,63 +6,68 @@ namespace rsx { + texture::texture(u8 idx, std::array &r) : m_index(idx), registers(r) + { + + } + void texture::init(u8 index) { m_index = index; // Offset - method_registers[NV4097_SET_TEXTURE_OFFSET + (m_index * 8)] = 0; + registers[NV4097_SET_TEXTURE_OFFSET + (m_index * 8)] = 0; // Format - method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] = 0; + registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] = 0; // Address - method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] = + registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] = ((/*wraps*/1) | ((/*anisoBias*/0) << 4) | ((/*wrapt*/1) << 8) | ((/*unsignedRemap*/0) << 12) | ((/*wrapr*/3) << 16) | ((/*gamma*/0) << 20) | ((/*signedRemap*/0) << 24) | ((/*zfunc*/0) << 28)); // Control0 - method_registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] = + registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] = (((/*alphakill*/0) << 2) | (/*maxaniso*/0) << 4) | ((/*maxlod*/0xc00) << 7) | ((/*minlod*/0) << 19) | ((/*enable*/0) << 31); // Control1 - method_registers[NV4097_SET_TEXTURE_CONTROL1 + (m_index * 8)] = 0xE4; + registers[NV4097_SET_TEXTURE_CONTROL1 + (m_index * 8)] = 0xE4; // Filter - method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] = + registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] = ((/*bias*/0) | ((/*conv*/1) << 13) | ((/*min*/5) << 16) | ((/*mag*/2) << 24) | ((/*as*/0) << 28) | ((/*rs*/0) << 29) | ((/*gs*/0) << 30) | ((/*bs*/0) << 31)); // Image Rect - method_registers[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index * 8)] = (/*height*/1) | ((/*width*/1) << 16); + registers[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index * 8)] = (/*height*/1) | ((/*width*/1) << 16); // Border Color - method_registers[NV4097_SET_TEXTURE_BORDER_COLOR + (m_index * 8)] = 0; + registers[NV4097_SET_TEXTURE_BORDER_COLOR + (m_index * 8)] = 0; } u32 texture::offset() const { - return method_registers[NV4097_SET_TEXTURE_OFFSET + (m_index * 8)]; + return registers[NV4097_SET_TEXTURE_OFFSET + (m_index * 8)]; } u8 texture::location() const { - return (method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] & 0x3) - 1; + return (registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] & 0x3) - 1; } bool texture::cubemap() const { - return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 2) & 0x1); + return ((registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 2) & 0x1); } u8 texture::border_type() const { - return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 3) & 0x1); + return ((registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 3) & 0x1); } rsx::texture_dimension texture::dimension() const { - return rsx::to_texture_dimension((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 4) & 0xf); + return rsx::to_texture_dimension((registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 4) & 0xf); } rsx::texture_dimension_extended texture::get_extended_texture_dimension() const @@ -79,7 +84,7 @@ namespace rsx u8 texture::format() const { - return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 8) & 0xff); + return ((registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 8) & 0xff); } bool texture::is_compressed_format() const @@ -94,7 +99,7 @@ namespace rsx u16 texture::mipmap() const { - return ((method_registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 16) & 0xffff); + return ((registers[NV4097_SET_TEXTURE_FORMAT + (m_index * 8)] >> 16) & 0xffff); } u16 texture::get_exact_mipmap_count() const @@ -112,137 +117,142 @@ namespace rsx rsx::texture_wrap_mode texture::wrap_s() const { - return rsx::to_texture_wrap_mode((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)]) & 0xf); + return rsx::to_texture_wrap_mode((registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)]) & 0xf); } rsx::texture_wrap_mode texture::wrap_t() const { - return rsx::to_texture_wrap_mode((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 8) & 0xf); + return rsx::to_texture_wrap_mode((registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 8) & 0xf); } rsx::texture_wrap_mode texture::wrap_r() const { - return rsx::to_texture_wrap_mode((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 16) & 0xf); + return rsx::to_texture_wrap_mode((registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 16) & 0xf); } u8 texture::unsigned_remap() const { - return ((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 12) & 0xf); + return ((registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 12) & 0xf); } u8 texture::zfunc() const { - return ((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 28) & 0xf); + return ((registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 28) & 0xf); } u8 texture::gamma() const { - return ((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 20) & 0xf); + return ((registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 20) & 0xf); } u8 texture::aniso_bias() const { - return ((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 4) & 0xf); + return ((registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 4) & 0xf); } u8 texture::signed_remap() const { - return ((method_registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 24) & 0xf); + return ((registers[NV4097_SET_TEXTURE_ADDRESS + (m_index * 8)] >> 24) & 0xf); } bool texture::enabled() const { - return location() <= 1 && ((method_registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 31) & 0x1); + return location() <= 1 && ((registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 31) & 0x1); } u16 texture::min_lod() const { - return ((method_registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 19) & 0xfff); + return ((registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 19) & 0xfff); } u16 texture::max_lod() const { - return ((method_registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff); + return ((registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff); } rsx::texture_max_anisotropy texture::max_aniso() const { - return rsx::to_texture_max_anisotropy((method_registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 4) & 0x7); + return rsx::to_texture_max_anisotropy((registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 4) & 0x7); } bool texture::alpha_kill_enabled() const { - return ((method_registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 2) & 0x1); + return ((registers[NV4097_SET_TEXTURE_CONTROL0 + (m_index * 8)] >> 2) & 0x1); } u32 texture::remap() const { - return (method_registers[NV4097_SET_TEXTURE_CONTROL1 + (m_index * 8)]); + return (registers[NV4097_SET_TEXTURE_CONTROL1 + (m_index * 8)]); } float texture::bias() const { - return float(f16((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff)); + return float(f16((registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff)); } rsx::texture_minify_filter texture::min_filter() const { - return rsx::to_texture_minify_filter((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 16) & 0x7); + return rsx::to_texture_minify_filter((registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 16) & 0x7); } rsx::texture_magnify_filter texture::mag_filter() const { - return rsx::to_texture_magnify_filter((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 24) & 0x7); + return rsx::to_texture_magnify_filter((registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 24) & 0x7); } u8 texture::convolution_filter() const { - return ((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 13) & 0xf); + return ((registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 13) & 0xf); } bool texture::a_signed() const { - return ((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 28) & 0x1); + return ((registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 28) & 0x1); } bool texture::r_signed() const { - return ((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 29) & 0x1); + return ((registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 29) & 0x1); } bool texture::g_signed() const { - return ((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 30) & 0x1); + return ((registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 30) & 0x1); } bool texture::b_signed() const { - return ((method_registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 31) & 0x1); + return ((registers[NV4097_SET_TEXTURE_FILTER + (m_index * 8)] >> 31) & 0x1); } u16 texture::width() const { - return ((method_registers[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index * 8)] >> 16) & 0xffff); + return ((registers[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index * 8)] >> 16) & 0xffff); } u16 texture::height() const { - return ((method_registers[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index * 8)]) & 0xffff); + return ((registers[NV4097_SET_TEXTURE_IMAGE_RECT + (m_index * 8)]) & 0xffff); } u32 texture::border_color() const { - return method_registers[NV4097_SET_TEXTURE_BORDER_COLOR + (m_index * 8)]; + return registers[NV4097_SET_TEXTURE_BORDER_COLOR + (m_index * 8)]; } u16 texture::depth() const { - return method_registers[NV4097_SET_TEXTURE_CONTROL3 + m_index] >> 20; + return registers[NV4097_SET_TEXTURE_CONTROL3 + m_index] >> 20; } u32 texture::pitch() const { - return method_registers[NV4097_SET_TEXTURE_CONTROL3 + m_index] & 0xfffff; + return registers[NV4097_SET_TEXTURE_CONTROL3 + m_index] & 0xfffff; + } + + vertex_texture::vertex_texture(u8 idx, std::array &r) : m_index(idx), registers(r) + { + } void vertex_texture::init(u8 index) @@ -250,58 +260,58 @@ namespace rsx m_index = index; // Offset - method_registers[NV4097_SET_VERTEX_TEXTURE_OFFSET + (m_index * 8)] = 0; + registers[NV4097_SET_VERTEX_TEXTURE_OFFSET + (m_index * 8)] = 0; // Format - method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] = 0; + registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] = 0; // Address - method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] = + registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] = ((/*wraps*/1) | ((/*anisoBias*/0) << 4) | ((/*wrapt*/1) << 8) | ((/*unsignedRemap*/0) << 12) | ((/*wrapr*/3) << 16) | ((/*gamma*/0) << 20) | ((/*signedRemap*/0) << 24) | ((/*zfunc*/0) << 28)); // Control0 - method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] = + registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] = (((/*alphakill*/0) << 2) | (/*maxaniso*/0) << 4) | ((/*maxlod*/0xc00) << 7) | ((/*minlod*/0) << 19) | ((/*enable*/0) << 31); // Control1 - //method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL1 + (m_index * 8)] = 0xE4; + //registers[NV4097_SET_VERTEX_TEXTURE_CONTROL1 + (m_index * 8)] = 0xE4; // Filter - method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] = + registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] = ((/*bias*/0) | ((/*conv*/1) << 13) | ((/*min*/5) << 16) | ((/*mag*/2) << 24) | ((/*as*/0) << 28) | ((/*rs*/0) << 29) | ((/*gs*/0) << 30) | ((/*bs*/0) << 31)); // Image Rect - method_registers[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 8)] = (/*height*/1) | ((/*width*/1) << 16); + registers[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 8)] = (/*height*/1) | ((/*width*/1) << 16); // Border Color - method_registers[NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + (m_index * 8)] = 0; + registers[NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + (m_index * 8)] = 0; } u32 vertex_texture::offset() const { - return method_registers[NV4097_SET_VERTEX_TEXTURE_OFFSET + (m_index * 8)]; + return registers[NV4097_SET_VERTEX_TEXTURE_OFFSET + (m_index * 8)]; } u8 vertex_texture::location() const { - return (method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] & 0x3) - 1; + return (registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] & 0x3) - 1; } bool vertex_texture::cubemap() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 2) & 0x1); + return ((registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 2) & 0x1); } u8 vertex_texture::border_type() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 3) & 0x1); + return ((registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 3) & 0x1); } rsx::texture_dimension vertex_texture::dimension() const { - return rsx::to_texture_dimension((method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 4) & 0xf); + return rsx::to_texture_dimension((registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 4) & 0xf); } rsx::texture_dimension_extended vertex_texture::get_extended_texture_dimension() const @@ -318,12 +328,12 @@ namespace rsx u8 vertex_texture::format() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 8) & 0xff); + return ((registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 8) & 0xff); } u16 vertex_texture::mipmap() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 16) & 0xffff); + return ((registers[NV4097_SET_VERTEX_TEXTURE_FORMAT + (m_index * 8)] >> 16) & 0xffff); } u16 vertex_texture::get_exact_mipmap_count() const @@ -334,116 +344,116 @@ namespace rsx u8 vertex_texture::unsigned_remap() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 12) & 0xf); + return ((registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 12) & 0xf); } u8 vertex_texture::zfunc() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 28) & 0xf); + return ((registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 28) & 0xf); } u8 vertex_texture::gamma() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 20) & 0xf); + return ((registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 20) & 0xf); } u8 vertex_texture::aniso_bias() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 4) & 0xf); + return ((registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 4) & 0xf); } u8 vertex_texture::signed_remap() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 24) & 0xf); + return ((registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 24) & 0xf); } bool vertex_texture::enabled() const { - return location() <= 1 && ((method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 31) & 0x1); + return location() <= 1 && ((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 31) & 0x1); } u16 vertex_texture::min_lod() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 19) & 0xfff); + return ((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 19) & 0xfff); } u16 vertex_texture::max_lod() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff); + return ((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 7) & 0xfff); } rsx::texture_max_anisotropy vertex_texture::max_aniso() const { - return rsx::to_texture_max_anisotropy((method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 4) & 0x7); + return rsx::to_texture_max_anisotropy((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 4) & 0x7); } bool vertex_texture::alpha_kill_enabled() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 2) & 0x1); + return ((registers[NV4097_SET_VERTEX_TEXTURE_CONTROL0 + (m_index * 8)] >> 2) & 0x1); } u16 vertex_texture::bias() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff); + return ((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)]) & 0x1fff); } rsx::texture_minify_filter vertex_texture::min_filter() const { - return rsx::to_texture_minify_filter((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 16) & 0x7); + return rsx::to_texture_minify_filter((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 16) & 0x7); } rsx::texture_magnify_filter vertex_texture::mag_filter() const { - return rsx::to_texture_magnify_filter((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 24) & 0x7); + return rsx::to_texture_magnify_filter((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 24) & 0x7); } u8 vertex_texture::convolution_filter() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 13) & 0xf); + return ((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 13) & 0xf); } bool vertex_texture::a_signed() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 28) & 0x1); + return ((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 28) & 0x1); } bool vertex_texture::r_signed() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 29) & 0x1); + return ((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 29) & 0x1); } bool vertex_texture::g_signed() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 30) & 0x1); + return ((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 30) & 0x1); } bool vertex_texture::b_signed() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 31) & 0x1); + return ((registers[NV4097_SET_VERTEX_TEXTURE_FILTER + (m_index * 8)] >> 31) & 0x1); } u16 vertex_texture::width() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 8)] >> 16) & 0xffff); + return ((registers[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 8)] >> 16) & 0xffff); } u16 vertex_texture::height() const { - return ((method_registers[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 8)]) & 0xffff); + return ((registers[NV4097_SET_VERTEX_TEXTURE_IMAGE_RECT + (m_index * 8)]) & 0xffff); } u32 vertex_texture::border_color() const { - return method_registers[NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + (m_index * 8)]; + return registers[NV4097_SET_VERTEX_TEXTURE_BORDER_COLOR + (m_index * 8)]; } u16 vertex_texture::depth() const { - return method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL3 + (m_index * 8)] >> 20; + return registers[NV4097_SET_VERTEX_TEXTURE_CONTROL3 + (m_index * 8)] >> 20; } u32 vertex_texture::pitch() const { - return method_registers[NV4097_SET_VERTEX_TEXTURE_CONTROL3 + (m_index * 8)] & 0xfffff; + return registers[NV4097_SET_VERTEX_TEXTURE_CONTROL3 + (m_index * 8)] & 0xfffff; } } \ No newline at end of file diff --git a/rpcs3/Emu/RSX/RSXTexture.h b/rpcs3/Emu/RSX/RSXTexture.h index 9c258b75c9..2274832e7b 100644 --- a/rpcs3/Emu/RSX/RSXTexture.h +++ b/rpcs3/Emu/RSX/RSXTexture.h @@ -18,8 +18,12 @@ namespace rsx { protected: u8 m_index; + std::array ®isters; public: + texture(u8 idx, std::array &r); + texture() = delete; + //initialize texture registers with default values void init(u8 index); @@ -90,8 +94,12 @@ namespace rsx { protected: u8 m_index; + std::array ®isters; public: + vertex_texture(u8 idx, std::array &r); + vertex_texture() = delete; + //initialize texture registers with default values void init(u8 index); diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 6393cea19d..3560126866 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -303,15 +303,13 @@ namespace rsx { frame_capture_data::draw_state draw_state = {}; - int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; - int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; - rsx::surface_info surface = {}; - surface.unpack(rsx::method_registers[NV4097_SET_SURFACE_FORMAT]); + int clip_w = rsx::method_registers.surface_clip_width(); + int clip_h = rsx::method_registers.surface_clip_height(); draw_state.width = clip_w; draw_state.height = clip_h; - draw_state.color_format = surface.color_format; + draw_state.color_format = rsx::method_registers.surface_color(); draw_state.color_buffer = std::move(copy_render_targets_to_memory()); - draw_state.depth_format = surface.depth_format; + draw_state.depth_format = rsx::method_registers.surface_depth_fmt(); draw_state.depth_stencil = std::move(copy_depth_stencil_buffer_to_memory()); if (draw_command == rsx::draw_command::indexed) @@ -321,7 +319,7 @@ namespace rsx { draw_state.vertex_count += range.second; } - draw_state.index_type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4); + draw_state.index_type = rsx::method_registers.index_type(); if (draw_state.index_type == rsx::index_array_type::u16) { @@ -346,17 +344,17 @@ namespace rsx inline_vertex_array.clear(); first_count_commands.clear(); draw_command = rsx::draw_command::none; - draw_mode = to_primitive_type(method_registers[NV4097_SET_BEGIN_END]); + draw_mode = method_registers.primitive_mode(); } void thread::end() { - transform_constants.clear(); + rsx::method_registers.transform_constants.clear(); for (u8 index = 0; index < rsx::limits::vertex_count; ++index) { - register_vertex_info[index].size = 0; - register_vertex_data[index].clear(); + rsx::method_registers.register_vertex_info[index].size = 0; + rsx::method_registers.register_vertex_data[index].clear(); } if (capture_current_frame) @@ -494,21 +492,21 @@ namespace rsx void thread::fill_scale_offset_data(void *buffer, bool is_d3d) const { - int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; - int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; + int clip_w = rsx::method_registers.surface_clip_width(); + int clip_h = rsx::method_registers.surface_clip_height(); - float scale_x = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE] / (clip_w / 2.f); - float offset_x = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET] - (clip_w / 2.f); + float scale_x = rsx::method_registers.viewport_scale_x() / (clip_w / 2.f); + float offset_x = rsx::method_registers.viewport_offset_x() - (clip_w / 2.f); offset_x /= clip_w / 2.f; - float scale_y = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 1] / (clip_h / 2.f); - float offset_y = ((float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 1] - (clip_h / 2.f)); + float scale_y = rsx::method_registers.viewport_scale_y() / (clip_h / 2.f); + float offset_y = (rsx::method_registers.viewport_offset_y() - (clip_h / 2.f)); offset_y /= clip_h / 2.f; if (is_d3d) scale_y *= -1; if (is_d3d) offset_y *= -1; - float scale_z = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 2]; - float offset_z = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 2]; + float scale_z = rsx::method_registers.viewport_scale_z(); + float offset_z = rsx::method_registers.viewport_offset_z(); if (!is_d3d) offset_z -= .5; float one = 1.f; @@ -525,7 +523,7 @@ namespace rsx */ void thread::fill_vertex_program_constants_data(void *buffer) { - for (const auto &entry : transform_constants) + for (const auto &entry : rsx::method_registers.transform_constants) local_transform_constants[entry.first] = entry.second; for (const auto &entry : local_transform_constants) stream_vector_from_memory((char*)buffer + entry.first * 4 * sizeof(float), (void*)entry.second.rgba); @@ -541,7 +539,7 @@ namespace rsx { for (int index = 0; index < rsx::limits::vertex_count; ++index) { - const auto &info = vertex_arrays_info[index]; + const auto &info = rsx::method_registers.vertex_arrays_info[index]; if (!info.size) // disabled continue; @@ -642,17 +640,17 @@ namespace rsx { u32 offset_color[] = { - rsx::method_registers[NV4097_SET_SURFACE_COLOR_AOFFSET], - rsx::method_registers[NV4097_SET_SURFACE_COLOR_BOFFSET], - rsx::method_registers[NV4097_SET_SURFACE_COLOR_COFFSET], - rsx::method_registers[NV4097_SET_SURFACE_COLOR_DOFFSET] + rsx::method_registers.surface_a_offset(), + rsx::method_registers.surface_b_offset(), + rsx::method_registers.surface_c_offset(), + rsx::method_registers.surface_d_offset(), }; u32 context_dma_color[] = { - rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_A], - rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_B], - rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_C], - rsx::method_registers[NV4097_SET_CONTEXT_DMA_COLOR_D] + rsx::method_registers.surface_a_dma(), + rsx::method_registers.surface_b_dma(), + rsx::method_registers.surface_c_dma(), + rsx::method_registers.surface_d_dma(), }; return { @@ -665,32 +663,32 @@ namespace rsx u32 thread::get_zeta_surface_address() const { - u32 m_context_dma_z = rsx::method_registers[NV4097_SET_CONTEXT_DMA_ZETA]; - u32 offset_zeta = rsx::method_registers[NV4097_SET_SURFACE_ZETA_OFFSET]; + u32 m_context_dma_z = rsx::method_registers.surface_z_dma(); + u32 offset_zeta = rsx::method_registers.surface_z_offset(); return rsx::get_address(offset_zeta, m_context_dma_z); } RSXVertexProgram thread::get_current_vertex_program() const { RSXVertexProgram result = {}; - u32 transform_program_start = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START]; + u32 transform_program_start = rsx::method_registers.transform_program_start(); result.data.reserve((512 - transform_program_start) * 4); for (int i = transform_program_start; i < 512; ++i) { result.data.resize((i - transform_program_start) * 4 + 4); - memcpy(result.data.data() + (i - transform_program_start) * 4, transform_program + i * 4, 4 * sizeof(u32)); + memcpy(result.data.data() + (i - transform_program_start) * 4, rsx::method_registers.transform_program.data() + i * 4, 4 * sizeof(u32)); D3 d3; - d3.HEX = transform_program[i * 4 + 3]; + d3.HEX = rsx::method_registers.transform_program[i * 4 + 3]; if (d3.end) break; } - result.output_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK]; + result.output_mask = rsx::method_registers.vertex_attrib_output_mask(); - u32 input_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK]; - u32 modulo_mask = rsx::method_registers[NV4097_SET_FREQUENCY_DIVIDER_OPERATION]; + u32 input_mask = rsx::method_registers.vertex_attrib_input_mask(); + u32 modulo_mask = rsx::method_registers.frequency_divider_operation_mask(); result.rsx_vertex_inputs.clear(); for (u8 index = 0; index < rsx::limits::vertex_count; ++index) { @@ -698,29 +696,29 @@ namespace rsx if (!enabled) continue; - if (vertex_arrays_info[index].size > 0) + if (rsx::method_registers.vertex_arrays_info[index].size > 0) { result.rsx_vertex_inputs.push_back( { index, - vertex_arrays_info[index].size, - vertex_arrays_info[index].frequency, + rsx::method_registers.vertex_arrays_info[index].size, + rsx::method_registers.vertex_arrays_info[index].frequency, !!((modulo_mask >> index) & 0x1), true, - is_int_type(vertex_arrays_info[index].type) + is_int_type(rsx::method_registers.vertex_arrays_info[index].type) } ); } - else if (register_vertex_info[index].size > 0) + else if (rsx::method_registers.register_vertex_info[index].size > 0) { result.rsx_vertex_inputs.push_back( { index, - register_vertex_info[index].size, - register_vertex_info[index].frequency, + rsx::method_registers.register_vertex_info[index].size, + rsx::method_registers.register_vertex_info[index].frequency, !!((modulo_mask >> index) & 0x1), false, - is_int_type(vertex_arrays_info[index].type) + is_int_type(rsx::method_registers.vertex_arrays_info[index].type) } ); } @@ -732,29 +730,28 @@ namespace rsx RSXFragmentProgram thread::get_current_fragment_program() const { RSXFragmentProgram result = {}; - u32 shader_program = rsx::method_registers[NV4097_SET_SHADER_PROGRAM]; + u32 shader_program = rsx::method_registers.shader_program_address(); result.offset = shader_program & ~0x3; result.addr = vm::base(rsx::get_address(result.offset, (shader_program & 0x3) - 1)); - result.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL]; + result.ctrl = rsx::method_registers.shader_control(); result.unnormalized_coords = 0; - result.front_back_color_enabled = !rsx::method_registers[NV4097_SET_TWO_SIDE_LIGHT_EN]; - result.back_color_diffuse_output = !!(rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK] & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE); - result.back_color_specular_output = !!(rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK] & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR); - result.alpha_func = to_comparaison_function(rsx::method_registers[NV4097_SET_ALPHA_FUNC]); - result.fog_equation = rsx::to_fog_mode(rsx::method_registers[NV4097_SET_FOG_MODE]); - u32 shader_window = rsx::method_registers[NV4097_SET_SHADER_WINDOW]; - result.origin_mode = rsx::to_window_origin((shader_window >> 12) & 0xF); - result.pixel_center_mode = rsx::to_window_pixel_center((shader_window >> 16) & 0xF); - result.height = shader_window & 0xFFF; + result.front_back_color_enabled = !rsx::method_registers.two_side_light_en(); + result.back_color_diffuse_output = !!(rsx::method_registers.vertex_attrib_output_mask() & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKDIFFUSE); + result.back_color_specular_output = !!(rsx::method_registers.vertex_attrib_output_mask() & CELL_GCM_ATTRIB_OUTPUT_MASK_BACKSPECULAR); + result.alpha_func = rsx::method_registers.alpha_func(); + result.fog_equation = rsx::method_registers.fog_equation(); + result.origin_mode = rsx::method_registers.shader_window_origin(); + result.pixel_center_mode = rsx::method_registers.shader_window_pixel(); + result.height = rsx::method_registers.shader_window_height(); std::array texture_dimensions; for (u32 i = 0; i < rsx::limits::textures_count; ++i) { - if (!textures[i].enabled()) + if (!rsx::method_registers.fragment_textures[i].enabled()) texture_dimensions[i] = texture_dimension_extended::texture_dimension_2d; else - texture_dimensions[i] = textures[i].get_extended_texture_dimension(); - if (textures[i].enabled() && (textures[i].format() & CELL_GCM_TEXTURE_UN)) + texture_dimensions[i] = rsx::method_registers.fragment_textures[i].get_extended_texture_dimension(); + if (rsx::method_registers.fragment_textures[i].enabled() && (rsx::method_registers.fragment_textures[i].format() & CELL_GCM_TEXTURE_UN)) result.unnormalized_coords |= (1 << i); } result.set_texture_dimension(texture_dimensions); @@ -766,29 +763,29 @@ namespace rsx { raw_program result{}; - u32 fp_info = rsx::method_registers[NV4097_SET_SHADER_PROGRAM]; + u32 fp_info = rsx::method_registers.shader_program_address(); - result.state.input_attributes = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK]; - result.state.output_attributes = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_OUTPUT_MASK]; - result.state.ctrl = rsx::method_registers[NV4097_SET_SHADER_CONTROL]; - result.state.divider_op = rsx::method_registers[NV4097_SET_FREQUENCY_DIVIDER_OPERATION]; - result.state.alpha_func = rsx::method_registers[NV4097_SET_ALPHA_FUNC]; - result.state.fog_mode = (u32)rsx::to_fog_mode(rsx::method_registers[NV4097_SET_FOG_MODE]); + result.state.input_attributes = rsx::method_registers.vertex_attrib_input_mask(); + result.state.output_attributes = rsx::method_registers.vertex_attrib_output_mask(); + result.state.ctrl = rsx::method_registers.shader_control(); + result.state.divider_op = rsx::method_registers.frequency_divider_operation_mask(); + result.state.alpha_func = (u32)rsx::method_registers.alpha_func(); + result.state.fog_mode = (u32)rsx::method_registers.fog_equation(); result.state.is_int = 0; for (u8 index = 0; index < rsx::limits::vertex_count; ++index) { bool is_int = false; - if (vertex_arrays_info[index].size > 0) + if (rsx::method_registers.vertex_arrays_info[index].size > 0) { - is_int = is_int_type(vertex_arrays_info[index].type); - result.state.frequency[index] = vertex_arrays_info[index].frequency; + is_int = is_int_type(rsx::method_registers.vertex_arrays_info[index].type); + result.state.frequency[index] = rsx::method_registers.vertex_arrays_info[index].frequency; } - else if (register_vertex_info[index].size > 0) + else if (rsx::method_registers.register_vertex_info[index].size > 0) { - is_int = is_int_type(register_vertex_info[index].type); - result.state.frequency[index] = register_vertex_info[index].frequency; + is_int = is_int_type(rsx::method_registers.register_vertex_info[index].type); + result.state.frequency[index] = rsx::method_registers.register_vertex_info[index].frequency; } else { @@ -803,7 +800,7 @@ namespace rsx for (u8 index = 0; index < rsx::limits::textures_count; ++index) { - if (!textures[index].enabled()) + if (!rsx::method_registers.fragment_textures[index].enabled()) { result.state.textures_alpha_kill[index] = 0; result.state.textures_zfunc[index] = 0; @@ -811,10 +808,10 @@ namespace rsx continue; } - result.state.textures_alpha_kill[index] = textures[index].alpha_kill_enabled() ? 1 : 0; - result.state.textures_zfunc[index] = textures[index].zfunc(); + result.state.textures_alpha_kill[index] = rsx::method_registers.fragment_textures[index].alpha_kill_enabled() ? 1 : 0; + result.state.textures_zfunc[index] = rsx::method_registers.fragment_textures[index].zfunc(); - switch (textures[index].get_extended_texture_dimension()) + switch (rsx::method_registers.fragment_textures[index].get_extended_texture_dimension()) { case rsx::texture_dimension_extended::texture_dimension_1d: result.state.textures[index] = rsx::texture_target::_1; break; case rsx::texture_dimension_extended::texture_dimension_2d: result.state.textures[index] = rsx::texture_target::_2; break; @@ -829,13 +826,13 @@ namespace rsx for (u8 index = 0; index < rsx::limits::vertex_textures_count; ++index) { - if (!textures[index].enabled()) + if (!rsx::method_registers.fragment_textures[index].enabled()) { result.state.vertex_textures[index] = rsx::texture_target::none; continue; } - switch (textures[index].get_extended_texture_dimension()) + switch (rsx::method_registers.fragment_textures[index].get_extended_texture_dimension()) { case rsx::texture_dimension_extended::texture_dimension_1d: result.state.vertex_textures[index] = rsx::texture_target::_1; break; case rsx::texture_dimension_extended::texture_dimension_2d: result.state.vertex_textures[index] = rsx::texture_target::_2; break; @@ -848,8 +845,8 @@ namespace rsx } } - result.vertex_shader.ucode_ptr = transform_program; - result.vertex_shader.offset = rsx::method_registers[NV4097_SET_TRANSFORM_PROGRAM_START]; + result.vertex_shader.ucode_ptr = rsx::method_registers.transform_program.data(); + result.vertex_shader.offset = rsx::method_registers.transform_program_start(); result.fragment_shader.ucode_ptr = vm::base(rsx::get_address(fp_info & ~0x3, (fp_info & 0x3) - 1)); result.fragment_shader.offset = 0; @@ -859,90 +856,7 @@ namespace rsx void thread::reset() { - //setup method registers - std::memset(method_registers, 0, sizeof(method_registers)); - - method_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; - method_registers[NV4097_SET_SCISSOR_HORIZONTAL] = (4096 << 16) | 0; - method_registers[NV4097_SET_SCISSOR_VERTICAL] = (4096 << 16) | 0; - - method_registers[NV4097_SET_ALPHA_FUNC] = CELL_GCM_ALWAYS; - method_registers[NV4097_SET_ALPHA_REF] = 0; - - method_registers[NV4097_SET_BLEND_FUNC_SFACTOR] = (CELL_GCM_ONE << 16) | CELL_GCM_ONE; - method_registers[NV4097_SET_BLEND_FUNC_DFACTOR] = (CELL_GCM_ZERO << 16) | CELL_GCM_ZERO; - method_registers[NV4097_SET_BLEND_COLOR] = 0; - method_registers[NV4097_SET_BLEND_COLOR2] = 0; - method_registers[NV4097_SET_BLEND_EQUATION] = (CELL_GCM_FUNC_ADD << 16) | CELL_GCM_FUNC_ADD; - - method_registers[NV4097_SET_STENCIL_MASK] = 0xff; - method_registers[NV4097_SET_STENCIL_FUNC] = CELL_GCM_ALWAYS; - method_registers[NV4097_SET_STENCIL_FUNC_REF] = 0x00; - method_registers[NV4097_SET_STENCIL_FUNC_MASK] = 0xff; - method_registers[NV4097_SET_STENCIL_OP_FAIL] = CELL_GCM_KEEP; - method_registers[NV4097_SET_STENCIL_OP_ZFAIL] = CELL_GCM_KEEP; - method_registers[NV4097_SET_STENCIL_OP_ZPASS] = CELL_GCM_KEEP; - - method_registers[NV4097_SET_BACK_STENCIL_MASK] = 0xff; - method_registers[NV4097_SET_BACK_STENCIL_FUNC] = CELL_GCM_ALWAYS; - method_registers[NV4097_SET_BACK_STENCIL_FUNC_REF] = 0x00; - method_registers[NV4097_SET_BACK_STENCIL_FUNC_MASK] = 0xff; - method_registers[NV4097_SET_BACK_STENCIL_OP_FAIL] = CELL_GCM_KEEP; - method_registers[NV4097_SET_BACK_STENCIL_OP_ZFAIL] = CELL_GCM_KEEP; - method_registers[NV4097_SET_BACK_STENCIL_OP_ZPASS] = CELL_GCM_KEEP; - - method_registers[NV4097_SET_SHADE_MODE] = CELL_GCM_SMOOTH; - - method_registers[NV4097_SET_LOGIC_OP] = CELL_GCM_COPY; - - (f32&)method_registers[NV4097_SET_DEPTH_BOUNDS_MIN] = 0.f; - (f32&)method_registers[NV4097_SET_DEPTH_BOUNDS_MAX] = 1.f; - - (f32&)method_registers[NV4097_SET_CLIP_MIN] = 0.f; - (f32&)method_registers[NV4097_SET_CLIP_MAX] = 1.f; - - method_registers[NV4097_SET_LINE_WIDTH] = 1 << 3; - - // These defaults were found using After Burner Climax (which never set fog mode despite using fog input) - method_registers[NV4097_SET_FOG_MODE] = 0x2601; // rsx::fog_mode::linear; - (f32&)method_registers[NV4097_SET_FOG_PARAMS] = 1.; - (f32&)method_registers[NV4097_SET_FOG_PARAMS + 1] = 1.; - - method_registers[NV4097_SET_DEPTH_FUNC] = CELL_GCM_LESS; - method_registers[NV4097_SET_DEPTH_MASK] = CELL_GCM_TRUE; - (f32&)method_registers[NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR] = 0.f; - (f32&)method_registers[NV4097_SET_POLYGON_OFFSET_BIAS] = 0.f; - method_registers[NV4097_SET_FRONT_POLYGON_MODE] = CELL_GCM_POLYGON_MODE_FILL; - method_registers[NV4097_SET_BACK_POLYGON_MODE] = CELL_GCM_POLYGON_MODE_FILL; - method_registers[NV4097_SET_CULL_FACE] = CELL_GCM_BACK; - method_registers[NV4097_SET_FRONT_FACE] = CELL_GCM_CCW; - method_registers[NV4097_SET_RESTART_INDEX] = -1; - - method_registers[NV4097_SET_CLEAR_RECT_HORIZONTAL] = (4096 << 16) | 0; - method_registers[NV4097_SET_CLEAR_RECT_VERTICAL] = (4096 << 16) | 0; - - method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffffff; - - method_registers[NV4097_SET_CONTEXT_DMA_REPORT] = CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT; - rsx::method_registers[NV4097_SET_TWO_SIDE_LIGHT_EN] = true; - rsx::method_registers[NV4097_SET_ALPHA_FUNC] = CELL_GCM_ALWAYS; - - // Reset vertex attrib array - for (int i = 0; i < limits::vertex_count; i++) - { - vertex_arrays_info[i].size = 0; - } - - // Construct Textures - for (int i = 0; i < limits::textures_count; i++) - { - textures[i].init(i); - } - - for (int i = 0; i < limits::vertex_textures_count; i++) - { - vertex_textures[i].init(i); - } + rsx::method_registers.reset(); } void thread::init(const u32 ioAddress, const u32 ioSize, const u32 ctrlAddress, const u32 localAddress) diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 10488e37c8..33b2237fd7 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -179,22 +179,6 @@ namespace rsx } }; - struct data_array_format_info - { - u16 frequency = 0; - u8 stride = 0; - u8 size = 0; - vertex_base_type type = vertex_base_type::f; - - void unpack_array(u32 data_array_format) - { - frequency = data_array_format >> 16; - stride = (data_array_format >> 8) & 0xff; - size = (data_array_format >> 4) & 0xf; - type = to_vertex_base_type(data_array_format & 0xf); - } - }; - enum class draw_command { none, @@ -219,33 +203,8 @@ namespace rsx GcmTileInfo tiles[limits::tiles_count]; GcmZcullInfo zculls[limits::zculls_count]; - rsx::texture textures[limits::textures_count]; - rsx::vertex_texture vertex_textures[limits::vertex_textures_count]; - - - /** - * RSX can sources vertex attributes from 2 places: - * - Immediate values passed by NV4097_SET_VERTEX_DATA*_M + ARRAY_ID write. - * For a given ARRAY_ID the last command of this type defines the actual type of the immediate value. - * Since there can be only a single value per ARRAY_ID passed this way, all vertex in the draw call - * shares it. - * - Vertex array values passed by offset/stride/size/format description. - * - * A given ARRAY_ID can have both an immediate value and a vertex array enabled at the same time - * (See After Burner Climax intro cutscene). In such case the vertex array has precedence over the - * immediate value. As soon as the vertex array is disabled (size set to 0) the immediate value - * must be used if the vertex attrib mask request it. - * - * Note that behavior when both vertex array and immediate value system are disabled but vertex attrib mask - * request inputs is unknow. - */ - data_array_format_info register_vertex_info[limits::vertex_count]; - std::vector register_vertex_data[limits::vertex_count]; - data_array_format_info vertex_arrays_info[limits::vertex_count]; u32 vertex_draw_count = 0; - std::unordered_map> transform_constants; - /** * Stores the first and count argument from draw/draw indexed parameters between begin/end clauses. */ @@ -254,8 +213,6 @@ namespace rsx // Constant stored for whole frame std::unordered_map local_transform_constants; - u32 transform_program[512 * 4] = {}; - bool capture_current_frame = false; void capture_frame(const std::string &name); diff --git a/rpcs3/Emu/RSX/VK/VKFormats.h b/rpcs3/Emu/RSX/VK/VKFormats.h index 376bf6f97b..95197228c9 100644 --- a/rpcs3/Emu/RSX/VK/VKFormats.h +++ b/rpcs3/Emu/RSX/VK/VKFormats.h @@ -12,9 +12,9 @@ namespace vk gpu_formats_support get_optimal_tiling_supported_formats(VkPhysicalDevice physical_device); VkFormat get_compatible_depth_surface_format(const gpu_formats_support &support, rsx::surface_depth_format format); - VkStencilOp get_stencil_op(u32 op); - VkLogicOp get_logic_op(u32 op); - VkFrontFace get_front_face_ccw(u32 ffv); + VkStencilOp get_stencil_op(rsx::stencil_op op); + VkLogicOp get_logic_op(rsx::logic_op op); + VkFrontFace get_front_face_ccw(rsx::front_face ffv); VkCullModeFlags get_cull_face(u32 cfv); VkBorderColor get_border_color(u8 color); diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index ba930606d3..15d6b720bb 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -31,26 +31,26 @@ namespace namespace vk { - VkCompareOp compare_op(u32 gl_name) + VkCompareOp compare_op(rsx::comparaison_function op) { - switch (gl_name) + switch (op) { - case CELL_GCM_NEVER: + case rsx::comparaison_function::never: return VK_COMPARE_OP_NEVER; - case CELL_GCM_GREATER: + case rsx::comparaison_function::greater: return VK_COMPARE_OP_GREATER; - case CELL_GCM_LESS: + case rsx::comparaison_function::less: return VK_COMPARE_OP_LESS; - case CELL_GCM_LEQUAL: + case rsx::comparaison_function::less_or_equal: return VK_COMPARE_OP_LESS_OR_EQUAL; - case CELL_GCM_GEQUAL: + case rsx::comparaison_function::greater_or_equal: return VK_COMPARE_OP_GREATER_OR_EQUAL; - case CELL_GCM_EQUAL: + case rsx::comparaison_function::equal: return VK_COMPARE_OP_EQUAL; - case CELL_GCM_ALWAYS: + case rsx::comparaison_function::always: return VK_COMPARE_OP_ALWAYS; default: - throw EXCEPTION("Unsupported compare op: 0x%X", gl_name); + throw EXCEPTION("Unsupported compare op: 0x%X", op); } } @@ -181,105 +181,106 @@ namespace vk } } - VkLogicOp get_logic_op(u32 op) + VkLogicOp get_logic_op(rsx::logic_op op) { switch (op) { - case CELL_GCM_CLEAR: return VK_LOGIC_OP_CLEAR; - case CELL_GCM_AND: return VK_LOGIC_OP_AND; - case CELL_GCM_AND_REVERSE: return VK_LOGIC_OP_AND_REVERSE; - case CELL_GCM_COPY: return VK_LOGIC_OP_COPY; - case CELL_GCM_AND_INVERTED: return VK_LOGIC_OP_AND_INVERTED; - case CELL_GCM_NOOP: return VK_LOGIC_OP_NO_OP; - case CELL_GCM_XOR: return VK_LOGIC_OP_XOR; - case CELL_GCM_OR: return VK_LOGIC_OP_OR; - case CELL_GCM_NOR: return VK_LOGIC_OP_NOR; - case CELL_GCM_EQUIV: return VK_LOGIC_OP_EQUIVALENT; - case CELL_GCM_INVERT: return VK_LOGIC_OP_INVERT; - case CELL_GCM_OR_REVERSE: return VK_LOGIC_OP_OR_REVERSE; - case CELL_GCM_COPY_INVERTED: return VK_LOGIC_OP_COPY_INVERTED; - case CELL_GCM_OR_INVERTED: return VK_LOGIC_OP_OR_INVERTED; - case CELL_GCM_NAND: return VK_LOGIC_OP_NAND; + case rsx::logic_op::logic_clear: return VK_LOGIC_OP_CLEAR; + case rsx::logic_op::logic_and: return VK_LOGIC_OP_AND; + case rsx::logic_op::logic_and_reverse: return VK_LOGIC_OP_AND_REVERSE; + case rsx::logic_op::logic_copy: return VK_LOGIC_OP_COPY; + case rsx::logic_op::logic_and_inverted: return VK_LOGIC_OP_AND_INVERTED; + case rsx::logic_op::logic_noop: return VK_LOGIC_OP_NO_OP; + case rsx::logic_op::logic_xor: return VK_LOGIC_OP_XOR; + case rsx::logic_op::logic_or : return VK_LOGIC_OP_OR; + case rsx::logic_op::logic_nor: return VK_LOGIC_OP_NOR; + case rsx::logic_op::logic_equiv: return VK_LOGIC_OP_EQUIVALENT; + case rsx::logic_op::logic_invert: return VK_LOGIC_OP_INVERT; + case rsx::logic_op::logic_or_reverse: return VK_LOGIC_OP_OR_REVERSE; + case rsx::logic_op::logic_copy_inverted: return VK_LOGIC_OP_COPY_INVERTED; + case rsx::logic_op::logic_or_inverted: return VK_LOGIC_OP_OR_INVERTED; + case rsx::logic_op::logic_nand: return VK_LOGIC_OP_NAND; default: throw EXCEPTION("Unknown logic op 0x%X", op); } } - VkBlendFactor get_blend_factor(u16 factor) + VkBlendFactor get_blend_factor(rsx::blend_factor factor) { switch (factor) { - case CELL_GCM_ONE: return VK_BLEND_FACTOR_ONE; - case CELL_GCM_ZERO: return VK_BLEND_FACTOR_ZERO; - case CELL_GCM_SRC_ALPHA: return VK_BLEND_FACTOR_SRC_ALPHA; - case CELL_GCM_DST_ALPHA: return VK_BLEND_FACTOR_DST_ALPHA; - case CELL_GCM_SRC_COLOR: return VK_BLEND_FACTOR_SRC_COLOR; - case CELL_GCM_DST_COLOR: return VK_BLEND_FACTOR_DST_COLOR; - case CELL_GCM_CONSTANT_COLOR: return VK_BLEND_FACTOR_CONSTANT_COLOR; - case CELL_GCM_CONSTANT_ALPHA: return VK_BLEND_FACTOR_CONSTANT_ALPHA; - case CELL_GCM_ONE_MINUS_SRC_COLOR: return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR; - case CELL_GCM_ONE_MINUS_DST_COLOR: return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR; - case CELL_GCM_ONE_MINUS_SRC_ALPHA: return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; - case CELL_GCM_ONE_MINUS_DST_ALPHA: return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA; - case CELL_GCM_ONE_MINUS_CONSTANT_ALPHA: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA; - case CELL_GCM_ONE_MINUS_CONSTANT_COLOR: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR; + case rsx::blend_factor::one: return VK_BLEND_FACTOR_ONE; + case rsx::blend_factor::zero: return VK_BLEND_FACTOR_ZERO; + case rsx::blend_factor::src_alpha: return VK_BLEND_FACTOR_SRC_ALPHA; + case rsx::blend_factor::dst_alpha: return VK_BLEND_FACTOR_DST_ALPHA; + case rsx::blend_factor::src_color: return VK_BLEND_FACTOR_SRC_COLOR; + case rsx::blend_factor::dst_color: return VK_BLEND_FACTOR_DST_COLOR; + case rsx::blend_factor::constant_color: return VK_BLEND_FACTOR_CONSTANT_COLOR; + case rsx::blend_factor::constant_alpha: return VK_BLEND_FACTOR_CONSTANT_ALPHA; + case rsx::blend_factor::one_minus_src_color: return VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR; + case rsx::blend_factor::one_minus_dst_color: return VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR; + case rsx::blend_factor::one_minus_src_alpha: return VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA; + case rsx::blend_factor::one_minus_dst_alpha: return VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA; + case rsx::blend_factor::one_minus_constant_alpha: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA; + case rsx::blend_factor::one_minus_constant_color: return VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR; default: throw EXCEPTION("Unknown blend factor 0x%X", factor); } }; - VkBlendOp get_blend_op(u16 op) + VkBlendOp get_blend_op(rsx::blend_equation op) { switch (op) { - case CELL_GCM_FUNC_ADD: return VK_BLEND_OP_ADD; - case CELL_GCM_FUNC_SUBTRACT: return VK_BLEND_OP_SUBTRACT; - case CELL_GCM_FUNC_REVERSE_SUBTRACT: return VK_BLEND_OP_REVERSE_SUBTRACT; - case CELL_GCM_MIN: return VK_BLEND_OP_MIN; - case CELL_GCM_MAX: return VK_BLEND_OP_MAX; + case rsx::blend_equation::add: return VK_BLEND_OP_ADD; + case rsx::blend_equation::substract: return VK_BLEND_OP_SUBTRACT; + case rsx::blend_equation::reverse_substract: return VK_BLEND_OP_REVERSE_SUBTRACT; + case rsx::blend_equation::min: return VK_BLEND_OP_MIN; + case rsx::blend_equation::max: return VK_BLEND_OP_MAX; default: throw EXCEPTION("Unknown blend op: 0x%X", op); } } - VkStencilOp get_stencil_op(u32 op) + + VkStencilOp get_stencil_op(rsx::stencil_op op) { switch (op) { - case CELL_GCM_KEEP: return VK_STENCIL_OP_KEEP; - case CELL_GCM_ZERO: return VK_STENCIL_OP_ZERO; - case CELL_GCM_REPLACE: return VK_STENCIL_OP_REPLACE; - case CELL_GCM_INCR: return VK_STENCIL_OP_INCREMENT_AND_CLAMP; - case CELL_GCM_DECR: return VK_STENCIL_OP_DECREMENT_AND_CLAMP; - case CELL_GCM_INVERT: return VK_STENCIL_OP_INVERT; - case CELL_GCM_INCR_WRAP: return VK_STENCIL_OP_INCREMENT_AND_WRAP; - case CELL_GCM_DECR_WRAP: return VK_STENCIL_OP_DECREMENT_AND_WRAP; + case rsx::stencil_op::keep: return VK_STENCIL_OP_KEEP; + case rsx::stencil_op::zero: return VK_STENCIL_OP_ZERO; + case rsx::stencil_op::replace: return VK_STENCIL_OP_REPLACE; + case rsx::stencil_op::incr: return VK_STENCIL_OP_INCREMENT_AND_CLAMP; + case rsx::stencil_op::decr: return VK_STENCIL_OP_DECREMENT_AND_CLAMP; + case rsx::stencil_op::invert: return VK_STENCIL_OP_INVERT; + case rsx::stencil_op::incr_wrap: return VK_STENCIL_OP_INCREMENT_AND_WRAP; + case rsx::stencil_op::decr_wrap: return VK_STENCIL_OP_DECREMENT_AND_WRAP; default: throw EXCEPTION("Unknown stencil op: 0x%X", op); } } - - VkFrontFace get_front_face_ccw(u32 ffv) + + VkFrontFace get_front_face_ccw(rsx::front_face ffv) { switch (ffv) { - default: // Disgaea 3 pass some garbage value at startup, this is needed to survive. - case CELL_GCM_CW: return VK_FRONT_FACE_CLOCKWISE; - case CELL_GCM_CCW: return VK_FRONT_FACE_COUNTER_CLOCKWISE; + case rsx::front_face::cw: return VK_FRONT_FACE_CLOCKWISE; + case rsx::front_face::ccw: return VK_FRONT_FACE_COUNTER_CLOCKWISE; + default: + throw EXCEPTION("Unknown front face value: 0x%X", ffv); } - throw EXCEPTION("Unknown front face value: 0x%X", ffv); } - VkCullModeFlags get_cull_face(u32 cfv) - { - switch (cfv) - { - case CELL_GCM_FRONT: return VK_CULL_MODE_FRONT_BIT; - case CELL_GCM_BACK: return VK_CULL_MODE_BACK_BIT; - case CELL_GCM_FRONT_AND_BACK: return VK_CULL_MODE_FRONT_AND_BACK; - default: return VK_CULL_MODE_NONE; - } - throw EXCEPTION("Unknown cull face value: 0x%X", cfv); + VkCullModeFlags get_cull_face(u32 cfv) + { + switch (cfv) + { + case CELL_GCM_FRONT: return VK_CULL_MODE_FRONT_BIT; + case CELL_GCM_BACK: return VK_CULL_MODE_BACK_BIT; + case CELL_GCM_FRONT_AND_BACK: return VK_CULL_MODE_FRONT_AND_BACK; + default: return VK_CULL_MODE_NONE; + } + throw EXCEPTION("Unknown cull face value: 0x%X", cfv); } } @@ -607,8 +608,7 @@ void VKGSRender::begin() if (!load_program()) return; - u32 line_width = rsx::method_registers[NV4097_SET_LINE_WIDTH]; - float actual_line_width = (line_width >> 3) + (line_width & 7) / 8.f; + float actual_line_width = rsx::method_registers.line_width(); vkCmdSetLineWidth(m_command_buffer, actual_line_width); @@ -639,35 +639,34 @@ namespace } - void VKGSRender::end() { size_t idx = vk::get_render_pass_location( - vk::get_compatible_surface_format(m_surface.color_format).first, - vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, m_surface.depth_format), - (u8)vk::get_draw_buffers(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])).size()); + vk::get_compatible_surface_format(rsx::method_registers.surface_color()).first, + vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, rsx::method_registers.surface_depth_fmt()), + (u8)vk::get_draw_buffers(rsx::method_registers.surface_color_target()).size()); VkRenderPass current_render_pass = m_render_passes[idx]; for (int i = 0; i < rsx::limits::textures_count; ++i) { if (m_program->has_uniform("tex" + std::to_string(i))) { - if (!textures[i].enabled()) + if (!rsx::method_registers.fragment_textures[i].enabled()) { m_program->bind_uniform({ vk::null_sampler(), vk::null_image_view(), VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, "tex" + std::to_string(i), descriptor_sets); continue; } - vk::image_view *texture0 = m_texture_cache.upload_texture(m_command_buffer, textures[i], m_rtts, m_memory_type_mapping, m_texture_upload_buffer_ring_info, m_texture_upload_buffer_ring_info.heap.get()); + vk::image_view *texture0 = m_texture_cache.upload_texture(m_command_buffer, rsx::method_registers.fragment_textures[i], m_rtts, m_memory_type_mapping, m_texture_upload_buffer_ring_info, m_texture_upload_buffer_ring_info.heap.get()); VkFilter min_filter; VkSamplerMipmapMode mip_mode; - std::tie(min_filter, mip_mode) = vk::get_min_filter_and_mip(textures[i].min_filter()); + std::tie(min_filter, mip_mode) = vk::get_min_filter_and_mip(rsx::method_registers.fragment_textures[i].min_filter()); m_sampler_to_clean.push_back(std::make_unique( *m_device, - vk::vk_wrap_mode(textures[i].wrap_s()), vk::vk_wrap_mode(textures[i].wrap_t()), vk::vk_wrap_mode(textures[i].wrap_r()), - !!(textures[i].format() & CELL_GCM_TEXTURE_UN), - textures[i].bias(), vk::max_aniso(textures[i].max_aniso()), textures[i].min_lod(), textures[i].max_lod(), - min_filter, vk::get_mag_filter(textures[i].mag_filter()), mip_mode, vk::get_border_color(textures[i].border_color()) + vk::vk_wrap_mode(rsx::method_registers.fragment_textures[i].wrap_s()), vk::vk_wrap_mode(rsx::method_registers.fragment_textures[i].wrap_t()), vk::vk_wrap_mode(rsx::method_registers.fragment_textures[i].wrap_r()), + !!(rsx::method_registers.fragment_textures[i].format() & CELL_GCM_TEXTURE_UN), + rsx::method_registers.fragment_textures[i].bias(), vk::max_aniso(rsx::method_registers.fragment_textures[i].max_aniso()), rsx::method_registers.fragment_textures[i].min_lod(), rsx::method_registers.fragment_textures[i].max_lod(), + min_filter, vk::get_mag_filter(rsx::method_registers.fragment_textures[i].mag_filter()), mip_mode, vk::get_border_color(rsx::method_registers.fragment_textures[i].border_color()) )); m_program->bind_uniform({ m_sampler_to_clean.back()->value, texture0->value, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL }, "tex" + std::to_string(i), descriptor_sets); } @@ -710,23 +709,18 @@ void VKGSRender::end() void VKGSRender::set_viewport() { - u32 viewport_horizontal = rsx::method_registers[NV4097_SET_VIEWPORT_HORIZONTAL]; - u32 viewport_vertical = rsx::method_registers[NV4097_SET_VIEWPORT_VERTICAL]; + u16 viewport_x = rsx::method_registers.viewport_origin_x(); + u16 viewport_y = rsx::method_registers.viewport_origin_y(); + u16 viewport_w = rsx::method_registers.viewport_width(); + u16 viewport_h = rsx::method_registers.viewport_height(); - u16 viewport_x = viewport_horizontal & 0xffff; - u16 viewport_y = viewport_vertical & 0xffff; - u16 viewport_w = viewport_horizontal >> 16; - u16 viewport_h = viewport_vertical >> 16; + u16 scissor_x = rsx::method_registers.scissor_origin_x(); + u16 scissor_w = rsx::method_registers.scissor_width(); + u16 scissor_y = rsx::method_registers.scissor_origin_y(); + u16 scissor_h = rsx::method_registers.scissor_height(); - u32 scissor_horizontal = rsx::method_registers[NV4097_SET_SCISSOR_HORIZONTAL]; - u32 scissor_vertical = rsx::method_registers[NV4097_SET_SCISSOR_VERTICAL]; - u16 scissor_x = scissor_horizontal; - u16 scissor_w = scissor_horizontal >> 16; - u16 scissor_y = scissor_vertical; - u16 scissor_h = scissor_vertical >> 16; - -// u32 shader_window = rsx::method_registers[NV4097_SET_SHADER_WINDOW]; -// rsx::window_origin shader_window_origin = rsx::to_window_origin((shader_window >> 12) & 0xf); + // u32 shader_window = rsx::method_registers[NV4097_SET_SHADER_WINDOW]; + // rsx::window_origin shader_window_origin = rsx::to_window_origin((shader_window >> 12) & 0xf); VkViewport viewport = {}; viewport.x = viewport_x; @@ -763,8 +757,7 @@ void VKGSRender::clear_surface(u32 mask) { //TODO: Build clear commands into current renderpass descriptor set if (!(mask & 0xF3)) return; - if (m_current_present_image== 0xFFFF) return; - if (!rsx::method_registers[NV4097_SET_SURFACE_FORMAT]) return; + if (m_current_present_image == 0xFFFF) return; init_buffers(); @@ -774,13 +767,13 @@ void VKGSRender::clear_surface(u32 mask) VkClearValue depth_stencil_clear_values, color_clear_values; VkImageSubresourceRange depth_range = vk::get_image_subresource_range(0, 0, 1, 1, 0); - rsx::surface_depth_format surface_depth_format = rsx::to_surface_depth_format((rsx::method_registers[NV4097_SET_SURFACE_FORMAT] >> 5) & 0x7); + rsx::surface_depth_format surface_depth_format = rsx::method_registers.surface_depth_fmt(); if (mask & 0x1) { u32 max_depth_value = get_max_depth_value(surface_depth_format); - u32 clear_depth = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] >> 8; + u32 clear_depth = rsx::method_registers.z_clear_value(); float depth_clear = (float)clear_depth / max_depth_value; depth_range.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT; @@ -790,8 +783,8 @@ void VKGSRender::clear_surface(u32 mask) if (mask & 0x2) { - u8 clear_stencil = rsx::method_registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] & 0xff; - u32 stencil_mask = rsx::method_registers[NV4097_SET_STENCIL_MASK]; + u8 clear_stencil = rsx::method_registers.stencil_clear_value(); + u32 stencil_mask = rsx::method_registers.stencil_mask(); //TODO set stencil mask depth_range.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; @@ -800,11 +793,10 @@ void VKGSRender::clear_surface(u32 mask) if (mask & 0xF0) { - u32 clear_color = rsx::method_registers[NV4097_SET_COLOR_CLEAR_VALUE]; - u8 clear_a = clear_color >> 24; - u8 clear_r = clear_color >> 16; - u8 clear_g = clear_color >> 8; - u8 clear_b = clear_color; + u8 clear_a = rsx::method_registers.clear_color_a(); + u8 clear_r = rsx::method_registers.clear_color_r(); + u8 clear_g = rsx::method_registers.clear_color_g(); + u8 clear_b = rsx::method_registers.clear_color_b(); //TODO set color mask /*VkBool32 clear_red = (VkBool32)!!(mask & 0x20); @@ -878,12 +870,12 @@ bool VKGSRender::load_program() bool unused; properties.ia.topology = vk::get_appropriate_topology(draw_mode, unused); - if (rsx::method_registers[NV4097_SET_RESTART_INDEX_ENABLE]) + if (rsx::method_registers.restart_index_enabled()) { - if (rsx::method_registers[NV4097_SET_RESTART_INDEX] != 0xFFFF && - rsx::method_registers[NV4097_SET_RESTART_INDEX] != 0xFFFFFFFF) + if (rsx::method_registers.restart_index() != 0xFFFF && + rsx::method_registers.restart_index() != 0xFFFFFFFF) { - LOG_ERROR(RSX, "Custom primitive restart index 0x%X. Should rewrite index buffer with proper value!", rsx::method_registers[NV4097_SET_RESTART_INDEX]); + LOG_ERROR(RSX, "Custom primitive restart index 0x%X. Should rewrite index buffer with proper value!", rsx::method_registers.restart_index()); } properties.ia.primitiveRestartEnable = VK_TRUE; } @@ -897,17 +889,11 @@ bool VKGSRender::load_program() properties.att_state[i].blendEnable = VK_FALSE; } - u32 color_mask = rsx::method_registers[NV4097_SET_COLOR_MASK]; - bool color_mask_b = !!(color_mask & 0xff); - bool color_mask_g = !!((color_mask >> 8) & 0xff); - bool color_mask_r = !!((color_mask >> 16) & 0xff); - bool color_mask_a = !!((color_mask >> 24) & 0xff); - VkColorComponentFlags mask = 0; - if (color_mask_a) mask |= VK_COLOR_COMPONENT_A_BIT; - if (color_mask_b) mask |= VK_COLOR_COMPONENT_B_BIT; - if (color_mask_g) mask |= VK_COLOR_COMPONENT_G_BIT; - if (color_mask_r) mask |= VK_COLOR_COMPONENT_R_BIT; + if (rsx::method_registers.color_mask_a()) mask |= VK_COLOR_COMPONENT_A_BIT; + if (rsx::method_registers.color_mask_b()) mask |= VK_COLOR_COMPONENT_B_BIT; + if (rsx::method_registers.color_mask_g()) mask |= VK_COLOR_COMPONENT_G_BIT; + if (rsx::method_registers.color_mask_r()) mask |= VK_COLOR_COMPONENT_R_BIT; VkColorComponentFlags color_masks[4] = { mask }; @@ -918,19 +904,15 @@ bool VKGSRender::load_program() properties.att_state[render_targets[idx]].colorWriteMask = mask; } - if (rsx::method_registers[NV4097_SET_BLEND_ENABLE]) + if (rsx::method_registers.blend_enabled()) { - u32 sfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_SFACTOR]; - u32 dfactor = rsx::method_registers[NV4097_SET_BLEND_FUNC_DFACTOR]; + VkBlendFactor sfactor_rgb = vk::get_blend_factor(rsx::method_registers.blend_func_sfactor_rgb()); + VkBlendFactor sfactor_a = vk::get_blend_factor(rsx::method_registers.blend_func_sfactor_a()); + VkBlendFactor dfactor_rgb = vk::get_blend_factor(rsx::method_registers.blend_func_dfactor_rgb()); + VkBlendFactor dfactor_a = vk::get_blend_factor(rsx::method_registers.blend_func_dfactor_a()); - VkBlendFactor sfactor_rgb = vk::get_blend_factor(sfactor); - VkBlendFactor sfactor_a = vk::get_blend_factor(sfactor >> 16); - VkBlendFactor dfactor_rgb = vk::get_blend_factor(dfactor); - VkBlendFactor dfactor_a = vk::get_blend_factor(dfactor >> 16); - - u32 equation = rsx::method_registers[NV4097_SET_BLEND_EQUATION]; - VkBlendOp equation_rgb = vk::get_blend_op(equation); - VkBlendOp equation_a = vk::get_blend_op(equation >> 16); + VkBlendOp equation_rgb = vk::get_blend_op(rsx::method_registers.blend_equation_rgb()); + VkBlendOp equation_a = vk::get_blend_op(rsx::method_registers.blend_equation_a()); //TODO: Separate target blending for (u8 idx = 0; idx < m_draw_buffers_count; ++idx) @@ -952,67 +934,83 @@ bool VKGSRender::load_program() } } - if (rsx::method_registers[NV4097_SET_LOGIC_OP_ENABLE]) + if (rsx::method_registers.logic_op_enabled()) { properties.cs.logicOpEnable = true; - properties.cs.logicOp = vk::get_logic_op(rsx::method_registers[NV4097_SET_LOGIC_OP]); + properties.cs.logicOp = vk::get_logic_op(rsx::method_registers.logic_operation()); } properties.ds.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; - properties.ds.depthWriteEnable = (!!rsx::method_registers[NV4097_SET_DEPTH_MASK]) ? VK_TRUE : VK_FALSE; + properties.ds.depthWriteEnable = rsx::method_registers.depth_write_enabled() ? VK_TRUE : VK_FALSE; - if (rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_TEST_ENABLE]) + if (rsx::method_registers.depth_bounds_test_enabled()) { properties.ds.depthBoundsTestEnable = VK_TRUE; - properties.ds.minDepthBounds = (f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MIN]; - properties.ds.maxDepthBounds = (f32&)rsx::method_registers[NV4097_SET_DEPTH_BOUNDS_MAX]; + properties.ds.minDepthBounds = rsx::method_registers.depth_bounds_min(); + properties.ds.maxDepthBounds = rsx::method_registers.depth_bounds_max(); } else properties.ds.depthBoundsTestEnable = VK_FALSE; - if (rsx::method_registers[NV4097_SET_STENCIL_TEST_ENABLE]) + if (rsx::method_registers.stencil_test_enabled()) { properties.ds.stencilTestEnable = VK_TRUE; - properties.ds.front.writeMask = rsx::method_registers[NV4097_SET_STENCIL_MASK]; - properties.ds.front.compareMask = rsx::method_registers[NV4097_SET_STENCIL_FUNC_MASK]; - properties.ds.front.reference = rsx::method_registers[NV4097_SET_STENCIL_FUNC_REF]; - properties.ds.front.failOp = vk::get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_FAIL]); - properties.ds.front.passOp = vk::get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_ZPASS]); - properties.ds.front.depthFailOp = vk::get_stencil_op(rsx::method_registers[NV4097_SET_STENCIL_OP_ZFAIL]); - properties.ds.front.compareOp = vk::compare_op(rsx::method_registers[NV4097_SET_STENCIL_FUNC]); + properties.ds.front.writeMask = rsx::method_registers.stencil_mask(); + properties.ds.front.compareMask = rsx::method_registers.stencil_func_mask(); + properties.ds.front.reference = rsx::method_registers.stencil_func_ref(); + properties.ds.front.failOp = vk::get_stencil_op(rsx::method_registers.stencil_op_fail()); + properties.ds.front.passOp = vk::get_stencil_op(rsx::method_registers.stencil_op_zpass()); + properties.ds.front.depthFailOp = vk::get_stencil_op(rsx::method_registers.stencil_op_zfail()); + properties.ds.front.compareOp = vk::compare_op(rsx::method_registers.stencil_func()); - if (rsx::method_registers[NV4097_SET_TWO_SIDED_STENCIL_TEST_ENABLE]) + if (rsx::method_registers.two_sided_stencil_test_enabled()) { - properties.ds.back.failOp = vk::get_stencil_op(rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_FAIL]); - properties.ds.back.passOp = vk::get_stencil_op(rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZPASS]); - properties.ds.back.depthFailOp = vk::get_stencil_op(rsx::method_registers[NV4097_SET_BACK_STENCIL_OP_ZFAIL]); - properties.ds.back.compareOp = vk::compare_op(rsx::method_registers[NV4097_SET_BACK_STENCIL_FUNC]); + properties.ds.back.failOp = vk::get_stencil_op(rsx::method_registers.back_stencil_op_fail()); + properties.ds.back.passOp = vk::get_stencil_op(rsx::method_registers.back_stencil_op_zpass()); + properties.ds.back.depthFailOp = vk::get_stencil_op(rsx::method_registers.back_stencil_op_zfail()); + properties.ds.back.compareOp = vk::compare_op(rsx::method_registers.back_stencil_func()); } else properties.ds.back = properties.ds.front; } else properties.ds.stencilTestEnable = VK_FALSE; - - if (!!rsx::method_registers[NV4097_SET_DEPTH_TEST_ENABLE]) + + if (rsx::method_registers.depth_test_enabled()) { properties.ds.depthTestEnable = VK_TRUE; - properties.ds.depthCompareOp = vk::compare_op(rsx::method_registers[NV4097_SET_DEPTH_FUNC]); + properties.ds.depthCompareOp = vk::compare_op(rsx::method_registers.depth_func()); } else properties.ds.depthTestEnable = VK_FALSE; - if (!!rsx::method_registers[NV4097_SET_CULL_FACE_ENABLE]) - { - properties.rs.cullMode = vk::get_cull_face(rsx::method_registers[NV4097_SET_CULL_FACE]); + if (rsx::method_registers.cull_face_enabled()) + { + switch (rsx::method_registers.cull_face_mode()) + { + case rsx::cull_face::front: + properties.rs.cullMode = VK_CULL_MODE_FRONT_BIT; + break; + case rsx::cull_face::back: + properties.rs.cullMode = VK_CULL_MODE_BACK_BIT; + break; + case rsx::cull_face::front_and_back: + properties.rs.cullMode = VK_CULL_MODE_FRONT_AND_BACK; + break; + default: + properties.rs.cullMode = VK_CULL_MODE_NONE; + break; + } } - - properties.rs.frontFace = vk::get_front_face_ccw(rsx::method_registers[NV4097_SET_FRONT_FACE]); - + else + properties.rs.cullMode = VK_CULL_MODE_NONE; + + properties.rs.frontFace = vk::get_front_face_ccw(rsx::method_registers.front_face_mode()); + size_t idx = vk::get_render_pass_location( - vk::get_compatible_surface_format(m_surface.color_format).first, - vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, m_surface.depth_format), - (u8)vk::get_draw_buffers(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])).size()); + vk::get_compatible_surface_format(rsx::method_registers.surface_color()).first, + vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, rsx::method_registers.surface_depth_fmt()), + (u8)vk::get_draw_buffers(rsx::method_registers.surface_color_target()).size()); properties.render_pass = m_render_passes[idx]; properties.num_targets = m_draw_buffers_count; @@ -1030,23 +1028,23 @@ bool VKGSRender::load_program() //TODO: Add case for this in RSXThread /** - * NOTE: While VK's coord system resembles GLs, the clip volume is no longer symetrical in z - * Its like D3D without the flip in y (depending on how you build the spir-v) - */ + * NOTE: While VK's coord system resembles GLs, the clip volume is no longer symetrical in z + * Its like D3D without the flip in y (depending on how you build the spir-v) + */ { - int clip_w = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL] >> 16; - int clip_h = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL] >> 16; + int clip_w = rsx::method_registers.surface_clip_width(); + int clip_h = rsx::method_registers.surface_clip_height(); - float scale_x = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE] / (clip_w / 2.f); - float offset_x = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET] - (clip_w / 2.f); + float scale_x = rsx::method_registers.viewport_scale_x() / (clip_w / 2.f); + float offset_x = rsx::method_registers.viewport_offset_x() - (clip_w / 2.f); offset_x /= clip_w / 2.f; - float scale_y = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 1] / (clip_h / 2.f); - float offset_y = ((float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 1] - (clip_h / 2.f)); + float scale_y = rsx::method_registers.viewport_scale_y() / (clip_h / 2.f); + float offset_y = (rsx::method_registers.viewport_offset_y() - (clip_h / 2.f)); offset_y /= clip_h / 2.f; - float scale_z = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_SCALE + 2]; - float offset_z = (float&)rsx::method_registers[NV4097_SET_VIEWPORT_OFFSET + 2]; + float scale_z = rsx::method_registers.viewport_scale_z(); + float offset_z = rsx::method_registers.viewport_offset_z(); float one = 1.f; @@ -1056,12 +1054,14 @@ bool VKGSRender::load_program() stream_vector((char*)buf + 48, 0, 0, 0, (u32&)one); } - u32 is_alpha_tested = !!(rsx::method_registers[NV4097_SET_ALPHA_TEST_ENABLE]); - u8 alpha_ref_raw = (u8)(rsx::method_registers[NV4097_SET_ALPHA_REF] & 0xFF); + u32 is_alpha_tested = rsx::method_registers.alpha_test_enabled(); + u8 alpha_ref_raw = rsx::method_registers.alpha_ref(); float alpha_ref = alpha_ref_raw / 255.f; - memcpy((char*)buf + 64, &rsx::method_registers[NV4097_SET_FOG_PARAMS], sizeof(float)); - memcpy((char*)buf + 68, &rsx::method_registers[NV4097_SET_FOG_PARAMS + 1], sizeof(float)); + f32 fog0 = rsx::method_registers.fog_params_0(); + f32 fog1 = rsx::method_registers.fog_params_1(); + memcpy((char*)buf + 64, &fog0, sizeof(float)); + memcpy((char*)buf + 68, &fog1, sizeof(float)); memcpy((char*)buf + 72, &is_alpha_tested, sizeof(u32)); memcpy((char*)buf + 76, &alpha_ref, sizeof(float)); m_uniform_buffer_ring_info.unmap(); @@ -1161,37 +1161,29 @@ void VKGSRender::open_command_buffer() void VKGSRender::prepare_rtts() { - u32 surface_format = rsx::method_registers[NV4097_SET_SURFACE_FORMAT]; - if (!m_rtts_dirty) return; m_rtts_dirty = false; - if (m_surface.format != surface_format) - m_surface.unpack(surface_format); - - u32 clip_horizontal = rsx::method_registers[NV4097_SET_SURFACE_CLIP_HORIZONTAL]; - u32 clip_vertical = rsx::method_registers[NV4097_SET_SURFACE_CLIP_VERTICAL]; - - u32 clip_width = clip_horizontal >> 16; - u32 clip_height = clip_vertical >> 16; - u32 clip_x = clip_horizontal; - u32 clip_y = clip_vertical; + u32 clip_width = rsx::method_registers.surface_clip_width(); + u32 clip_height = rsx::method_registers.surface_clip_height(); + u32 clip_x = rsx::method_registers.surface_clip_origin_x(); + u32 clip_y = rsx::method_registers.surface_clip_origin_y(); m_rtts.prepare_render_target(&m_command_buffer, - surface_format, - clip_horizontal, clip_vertical, - rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET]), + rsx::method_registers.surface_color(), rsx::method_registers.surface_depth_fmt(), + rsx::method_registers.surface_clip_width(), rsx::method_registers.surface_clip_height(), + rsx::method_registers.surface_color_target(), get_color_surface_addresses(), get_zeta_surface_address(), (*m_device), &m_command_buffer, m_optimal_tiling_supported_formats, m_memory_type_mapping); //Bind created rtts as current fbo... - std::vector draw_buffers = vk::get_draw_buffers(rsx::to_surface_target(rsx::method_registers[NV4097_SET_SURFACE_COLOR_TARGET])); + std::vector draw_buffers = vk::get_draw_buffers(rsx::method_registers.surface_color_target()); std::vector> fbo_images; - for (u8 index: draw_buffers) + for (u8 index : draw_buffers) { vk::image *raw = std::get<1>(m_rtts.m_bound_render_targets[index]); @@ -1212,7 +1204,7 @@ void VKGSRender::prepare_rtts() vk::image *raw = (std::get<1>(m_rtts.m_bound_depth_stencil)); VkImageSubresourceRange subres = {}; - subres.aspectMask = (m_surface.depth_format == rsx::surface_depth_format::z24s8) ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) : VK_IMAGE_ASPECT_DEPTH_BIT; + subres.aspectMask = (rsx::method_registers.surface_depth_fmt() == rsx::surface_depth_format::z24s8) ? (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT) : VK_IMAGE_ASPECT_DEPTH_BIT; subres.baseArrayLayer = 0; subres.baseMipLevel = 0; subres.layerCount = 1; @@ -1221,7 +1213,7 @@ void VKGSRender::prepare_rtts() fbo_images.push_back(std::make_unique(*m_device, raw->value, VK_IMAGE_VIEW_TYPE_2D, raw->info.format, vk::default_component_map(), subres)); } - size_t idx = vk::get_render_pass_location(vk::get_compatible_surface_format(m_surface.color_format).first, vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, m_surface.depth_format), (u8)draw_buffers.size()); + size_t idx = vk::get_render_pass_location(vk::get_compatible_surface_format(rsx::method_registers.surface_color()).first, vk::get_compatible_depth_surface_format(m_optimal_tiling_supported_formats, rsx::method_registers.surface_depth_fmt()), (u8)draw_buffers.size()); VkRenderPass current_render_pass = m_render_passes[idx]; m_framebuffer_to_clean.push_back(std::make_unique(*m_device, current_render_pass, clip_width, clip_height, std::move(fbo_images))); diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index 4b7e1b12c8..4d334710d6 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -21,8 +21,6 @@ private: vk::glsl::program *m_program; vk::context m_thread_context; - rsx::surface_info m_surface; - vk::vk_data_heap m_attrib_ring_info; vk::texture_cache m_texture_cache; diff --git a/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp b/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp index 69e320f1d3..cedf1200aa 100644 --- a/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp +++ b/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp @@ -301,7 +301,7 @@ VKGSRender::upload_vertex_data() "in_tc4_buffer", "in_tc5_buffer", "in_tc6_buffer", "in_tc7_buffer" }; - u32 input_mask = rsx::method_registers[NV4097_SET_VERTEX_ATTRIB_INPUT_MASK]; + u32 input_mask = rsx::method_registers.vertex_attrib_input_mask(); size_t offset_in_index_buffer = -1; vertex_draw_count = 0; @@ -324,7 +324,7 @@ VKGSRender::upload_vertex_data() if (draw_command == rsx::draw_command::indexed || primitives_emulated) { - rsx::index_array_type type = rsx::to_index_array_type(rsx::method_registers[NV4097_SET_INDEX_ARRAY_DMA] >> 4); + rsx::index_array_type type = rsx::method_registers.index_type(); u32 type_size = gsl::narrow(get_index_type_size(type)); if (is_indexed_draw) //Could be emulated or not, emulated array vertex count already computed above @@ -368,7 +368,7 @@ VKGSRender::upload_vertex_data() for (u32 i = 0; i < rsx::limits::vertex_count; ++i) { - const auto &info = vertex_arrays_info[i]; + const auto &info = rsx::method_registers.vertex_arrays_info[i]; if (!info.size) continue; offsets[i] = stride; @@ -379,7 +379,7 @@ VKGSRender::upload_vertex_data() for (int index = 0; index < rsx::limits::vertex_count; ++index) { - auto &vertex_info = vertex_arrays_info[index]; + auto &vertex_info = rsx::method_registers.vertex_arrays_info[index]; if (!m_program->has_uniform(reg_table[index])) continue; @@ -448,9 +448,9 @@ VKGSRender::upload_vertex_data() continue; } - if (vertex_arrays_info[index].size > 0) + if (rsx::method_registers.vertex_arrays_info[index].size > 0) { - auto &vertex_info = vertex_arrays_info[index]; + auto &vertex_info = rsx::method_registers.vertex_arrays_info[index]; // Fill vertex_array u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size); @@ -461,8 +461,8 @@ VKGSRender::upload_vertex_data() bool requires_expansion = vk::requires_component_expansion(vertex_info.type, vertex_info.size); // Get source pointer - u32 base_offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_BASE_OFFSET]; - u32 offset = rsx::method_registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + index]; + u32 base_offset = rsx::method_registers.vertex_data_base_offset(); + u32 offset = rsx::method_registers.vertex_arrays_info[index].offset(); u32 address = base_offset + rsx::get_address(offset & 0x7fffffff, offset >> 31); const gsl::byte *src_ptr = gsl::narrow_cast(vm::base(address)); @@ -505,11 +505,11 @@ VKGSRender::upload_vertex_data() m_buffer_view_to_clean.push_back(std::make_unique(*m_device, m_attrib_ring_info.heap->value, format, offset_in_attrib_buffer, upload_size)); m_program->bind_uniform(m_buffer_view_to_clean.back()->value, reg_table[index], descriptor_sets); } - else if (register_vertex_info[index].size > 0) + else if (rsx::method_registers.register_vertex_info[index].size > 0) { //Untested! - auto &vertex_data = register_vertex_data[index]; - auto &vertex_info = register_vertex_info[index]; + auto &vertex_data = rsx::method_registers.register_vertex_data[index]; + auto &vertex_info = rsx::method_registers.register_vertex_info[index]; switch (vertex_info.type) { diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index 03cea5e20e..921a598878 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -8,6 +8,7 @@ #include "Emu/Cell/PPUCallback.h" #include +#include cfg::map_entry g_cfg_rsx_frame_limit(cfg::root.video, "Frame limit", { @@ -21,7 +22,7 @@ cfg::map_entry g_cfg_rsx_frame_limit(cfg::root.video, "Frame limit", namespace rsx { - u32 method_registers[0x10000 >> 2]; + rsx_state method_registers; rsx_method_t methods[0x10000 >> 2]{}; template struct vertex_data_type_from_element_type; @@ -40,7 +41,7 @@ namespace rsx force_inline void semaphore_acquire(thread* rsx, u32 arg) { //TODO: dma - while (vm::ps3::read32(rsx->label_addr + method_registers[NV406E_SEMAPHORE_OFFSET]) != arg) + while (vm::ps3::read32(rsx->label_addr + method_registers.semaphore_offset_406e()) != arg) { if (Emu.IsStopped()) break; @@ -52,7 +53,7 @@ namespace rsx force_inline void semaphore_release(thread* rsx, u32 arg) { //TODO: dma - vm::ps3::write32(rsx->label_addr + method_registers[NV406E_SEMAPHORE_OFFSET], arg); + vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_406e(), arg); } } @@ -61,13 +62,13 @@ namespace rsx force_inline void texture_read_semaphore_release(thread* rsx, u32 arg) { //TODO: dma - vm::ps3::write32(rsx->label_addr + method_registers[NV4097_SET_SEMAPHORE_OFFSET], arg); + vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_4097(), arg); } force_inline void back_end_write_semaphore_release(thread* rsx, u32 arg) { //TODO: dma - vm::ps3::write32(rsx->label_addr + method_registers[NV4097_SET_SEMAPHORE_OFFSET], + vm::ps3::write32(rsx->label_addr + method_registers.semaphore_offset_4097(), (arg & 0xff00ff00) | ((arg & 0xff) << 16) | ((arg >> 16) & 0xff)); } @@ -78,14 +79,14 @@ namespace rsx static const size_t element_size = (count * sizeof(type)); static const size_t element_size_in_words = element_size / sizeof(u32); - auto& info = rsx->register_vertex_info[index]; + auto& info = rsx::method_registers.register_vertex_info[index]; info.type = vertex_data_type_from_element_type::type; info.size = count; info.frequency = 0; info.stride = 0; - auto& entry = rsx->register_vertex_data[index]; + auto& entry = rsx::method_registers.register_vertex_data[index]; //find begin of data size_t begin = id + index * element_size_in_words; @@ -93,7 +94,7 @@ namespace rsx size_t position = entry.size(); entry.resize(position + element_size); - memcpy(entry.data() + position, method_registers + begin, element_size); + memcpy(entry.data() + position, &method_registers[begin], element_size); } template @@ -164,7 +165,7 @@ namespace rsx { force_inline static void impl(thread* rsx, u32 arg) { - auto& info = rsx->vertex_arrays_info[index]; + auto& info = rsx::method_registers.vertex_arrays_info[index]; info.unpack_array(arg); } }; @@ -199,15 +200,7 @@ namespace rsx { force_inline static void impl(thread* rsxthr, u32 arg) { - u32 load = method_registers[NV4097_SET_TRANSFORM_CONSTANT_LOAD]; - - static const size_t count = 4; - static const size_t size = count * sizeof(f32); - - size_t reg = index / 4; - size_t subreg = index % 4; - - memcpy(rsxthr->transform_constants[load + reg].rgba + subreg, method_registers + NV4097_SET_TRANSFORM_CONSTANT + reg * count + subreg, sizeof(f32)); + method_registers.set_transform_constant(index, arg); rsxthr->m_transform_constants_dirty = true; } }; @@ -217,12 +210,7 @@ namespace rsx { force_inline static void impl(thread* rsx, u32 arg) { - u32& load = method_registers[NV4097_SET_TRANSFORM_PROGRAM_LOAD]; - - static const size_t count = 4; - static const size_t size = count * sizeof(u32); - - memcpy(rsx->transform_program + load++ * count, method_registers + NV4097_SET_TRANSFORM_PROGRAM + index * count, size); + method_registers.commit_4_transform_program_instructions(index); } }; @@ -238,17 +226,16 @@ namespace rsx for (u8 index = 0; index < rsx::limits::vertex_count; ++index) { - auto &vertex_info = rsxthr->register_vertex_info[index]; + auto &vertex_info = rsx::method_registers.register_vertex_info[index]; if (vertex_info.size > 0) { - auto &vertex_data = rsxthr->register_vertex_data[index]; + auto &vertex_data = rsx::method_registers.register_vertex_data[index]; u32 element_size = rsx::get_vertex_type_size_on_host(vertex_info.type, vertex_info.size); u32 element_count = vertex_data.size() / element_size; vertex_info.frequency = element_count; - rsx::method_registers[NV4097_SET_FREQUENCY_DIVIDER_OPERATION] |= 1 << index; if (rsxthr->draw_command == rsx::draw_command::none) { @@ -273,13 +260,13 @@ namespace rsx { u8 type = arg >> 24; u32 offset = arg & 0xffffff; - u32 report_dma = method_registers[NV4097_SET_CONTEXT_DMA_REPORT]; + blit_engine::context_dma report_dma = method_registers.context_dma_report(); u32 location; switch (report_dma) { - case CELL_GCM_CONTEXT_DMA_TO_MEMORY_GET_REPORT: location = CELL_GCM_LOCATION_LOCAL; break; - case CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_MAIN: location = CELL_GCM_LOCATION_MAIN; break; + case blit_engine::context_dma::to_memory_get_report: location = CELL_GCM_LOCATION_LOCAL; break; + case blit_engine::context_dma::report_location_main: location = CELL_GCM_LOCATION_MAIN; break; default: LOG_WARNING(RSX, "nv4097::get_report: bad report dma: 0x%x", report_dma); return; @@ -347,16 +334,15 @@ namespace rsx { force_inline static void impl(u32 arg) { - u32 point = method_registers[NV308A_POINT]; - u16 x = point; - u16 y = point >> 16; + u16 x = method_registers.nv308a_x(); + u16 y = method_registers.nv308a_y(); if (y) { LOG_ERROR(RSX, "%s: y is not null (0x%x)", __FUNCTION__, y); } - u32 address = get_address(method_registers[NV3062_SET_OFFSET_DESTIN] + (x << 2) + index * 4, method_registers[NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN]); + u32 address = get_address(method_registers.blit_engine_output_offset_nv3062() + (x << 2) + index * 4, method_registers.blit_engine_output_location_nv3062()); vm::ps3::write32(address, arg); } }; @@ -366,70 +352,65 @@ namespace rsx { never_inline void image_in(thread *rsx, u32 arg) { - u32 operation = method_registers[NV3089_SET_OPERATION]; + rsx::blit_engine::transfer_operation operation = method_registers.blit_engine_operation(); - u32 clip_x = method_registers[NV3089_CLIP_POINT] & 0xffff; - u32 clip_y = method_registers[NV3089_CLIP_POINT] >> 16; - u32 clip_w = method_registers[NV3089_CLIP_SIZE] & 0xffff; - u32 clip_h = method_registers[NV3089_CLIP_SIZE] >> 16; + u32 clip_x = method_registers.blit_engine_clip_x(); + u32 clip_y = method_registers.blit_engine_clip_y(); + u32 clip_w = method_registers.blit_engine_clip_width(); + u32 clip_h = method_registers.blit_engine_clip_height(); - u32 out_x = method_registers[NV3089_IMAGE_OUT_POINT] & 0xffff; - u32 out_y = method_registers[NV3089_IMAGE_OUT_POINT] >> 16; - u32 out_w = method_registers[NV3089_IMAGE_OUT_SIZE] & 0xffff; - u32 out_h = method_registers[NV3089_IMAGE_OUT_SIZE] >> 16; + u32 out_x = method_registers.blit_engine_output_x(); + u32 out_y = method_registers.blit_engine_output_y(); + u32 out_w = method_registers.blit_engine_clip_width(); + u32 out_h = method_registers.blit_engine_output_height(); - u16 in_w = method_registers[NV3089_IMAGE_IN_SIZE]; - u16 in_h = method_registers[NV3089_IMAGE_IN_SIZE] >> 16; - u16 in_pitch = method_registers[NV3089_IMAGE_IN_FORMAT]; - u8 in_origin = method_registers[NV3089_IMAGE_IN_FORMAT] >> 16; - u8 in_inter = method_registers[NV3089_IMAGE_IN_FORMAT] >> 24; - u32 src_color_format = method_registers[NV3089_SET_COLOR_FORMAT]; + u16 in_w = method_registers.blit_engine_input_width(); + u16 in_h = method_registers.blit_engine_output_height(); + u16 in_pitch = method_registers.blit_engine_input_pitch(); + blit_engine::transfer_origin in_origin = method_registers.blit_engine_input_origin(); + blit_engine::transfer_interpolator in_inter = method_registers.blit_engine_input_inter(); + rsx::blit_engine::transfer_source_format src_color_format = method_registers.blit_engine_src_color_format(); - f32 in_x = (method_registers[NV3089_IMAGE_IN] & 0xffff) / 16.f; - f32 in_y = (method_registers[NV3089_IMAGE_IN] >> 16) / 16.f; + f32 in_x = method_registers.blit_engine_in_x(); + f32 in_y = method_registers.blit_engine_in_y(); - if (in_origin != CELL_GCM_TRANSFER_ORIGIN_CORNER) + if (in_origin != blit_engine::transfer_origin::corner) { LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown origin (%d)", in_origin); } - if (in_inter != CELL_GCM_TRANSFER_INTERPOLATOR_ZOH && in_inter != CELL_GCM_TRANSFER_INTERPOLATOR_FOH) - { - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown inter (%d)", in_inter); - } - - if (operation != CELL_GCM_TRANSFER_OPERATION_SRCCOPY) + if (operation != rsx::blit_engine::transfer_operation::srccopy) { LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown operation (%d)", operation); } - const u32 src_offset = method_registers[NV3089_IMAGE_IN_OFFSET]; - const u32 src_dma = method_registers[NV3089_SET_CONTEXT_DMA_IMAGE]; + const u32 src_offset = method_registers.blit_engine_input_offset(); + const u32 src_dma = method_registers.blit_engine_input_location(); u32 dst_offset; u32 dst_dma = 0; - u16 dst_color_format; + rsx::blit_engine::transfer_destination_format dst_color_format; u32 out_pitch = 0; u32 out_aligment = 64; - switch (method_registers[NV3089_SET_CONTEXT_SURFACE]) + switch (method_registers.blit_engine_context_surface()) { - case CELL_GCM_CONTEXT_SURFACE2D: - dst_dma = method_registers[NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN]; - dst_offset = method_registers[NV3062_SET_OFFSET_DESTIN]; - dst_color_format = method_registers[NV3062_SET_COLOR_FORMAT]; - out_pitch = method_registers[NV3062_SET_PITCH] >> 16; - out_aligment = method_registers[NV3062_SET_PITCH] & 0xffff; + case blit_engine::context_surface::surface2d: + dst_dma = method_registers.blit_engine_output_location_nv3062(); + dst_offset = method_registers.blit_engine_output_offset_nv3062(); + dst_color_format = method_registers.blit_engine_nv3062_color_format(); + out_pitch = method_registers.blit_engine_output_pitch_nv3062(); + out_aligment = method_registers.blit_engine_output_alignment_nv3062(); break; - case CELL_GCM_CONTEXT_SWIZZLE2D: - dst_dma = method_registers[NV309E_SET_CONTEXT_DMA_IMAGE]; - dst_offset = method_registers[NV309E_SET_OFFSET]; - dst_color_format = method_registers[NV309E_SET_FORMAT]; + case blit_engine::context_surface::swizzle2d: + dst_dma = method_registers.blit_engine_nv309E_location(); + dst_offset = method_registers.blit_engine_nv309E_offset(); + dst_color_format = method_registers.blit_engine_output_format_nv309E(); break; default: - LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_context_surface (0x%x)", method_registers[NV3089_SET_CONTEXT_SURFACE]); + LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown m_context_surface (0x%x)", method_registers.blit_engine_context_surface()); return; } @@ -464,8 +445,8 @@ namespace rsx } } - u32 in_bpp = src_color_format == CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5 ? 2 : 4; // bytes per pixel - u32 out_bpp = dst_color_format == CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 ? 2 : 4; + u32 in_bpp = (src_color_format == rsx::blit_engine::transfer_source_format::r5g6b5) ? 2 : 4; // bytes per pixel + u32 out_bpp = (dst_color_format == rsx::blit_engine::transfer_destination_format::r5g6b5) ? 2 : 4; u32 in_offset = u32(in_x * in_bpp + in_pitch * in_y); u32 out_offset = out_x * out_bpp + out_pitch * out_y; @@ -498,14 +479,14 @@ namespace rsx u8* pixels_src = src_region.tile ? src_region.ptr + src_region.base : src_region.ptr; u8* pixels_dst = vm::ps3::_ptr(dst_address + out_offset); - if (dst_color_format != CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 && - dst_color_format != CELL_GCM_TRANSFER_SURFACE_FORMAT_A8R8G8B8) + if (dst_color_format != rsx::blit_engine::transfer_destination_format::r5g6b5 && + dst_color_format != rsx::blit_engine::transfer_destination_format::a8r8g8b8) { LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown dst_color_format (%d)", dst_color_format); } - if (src_color_format != CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5 && - src_color_format != CELL_GCM_TRANSFER_SCALE_FORMAT_A8R8G8B8) + if (src_color_format != rsx::blit_engine::transfer_source_format::r5g6b5 && + src_color_format != rsx::blit_engine::transfer_source_format::a8r8g8b8) { LOG_ERROR(RSX, "NV3089_IMAGE_IN_SIZE: unknown src_color_format (%d)", src_color_format); } @@ -516,18 +497,21 @@ namespace rsx std::unique_ptr temp1, temp2, sw_temp; - AVPixelFormat in_format = src_color_format == CELL_GCM_TRANSFER_SCALE_FORMAT_R5G6B5 ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_ARGB; - AVPixelFormat out_format = dst_color_format == CELL_GCM_TRANSFER_SURFACE_FORMAT_R5G6B5 ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_ARGB; + AVPixelFormat in_format = (src_color_format == rsx::blit_engine::transfer_source_format::r5g6b5) ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_ARGB; + AVPixelFormat out_format = (dst_color_format == rsx::blit_engine::transfer_destination_format::r5g6b5) ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_ARGB; - f32 scale_x = 1048576.f / method_registers[NV3089_DS_DX]; - f32 scale_y = 1048576.f / method_registers[NV3089_DT_DY]; + f32 scale_x = 1048576.f / method_registers.blit_engine_ds_dx(); + f32 scale_y = 1048576.f / method_registers.blit_engine_dt_dy(); u32 convert_w = (u32)(scale_x * in_w); u32 convert_h = (u32)(scale_y * in_h); bool need_clip = - method_registers[NV3089_CLIP_SIZE] != method_registers[NV3089_IMAGE_IN_SIZE] || - method_registers[NV3089_CLIP_POINT] || convert_w != out_w || convert_h != out_h; + method_registers.blit_engine_clip_width() != method_registers.blit_engine_input_width() || + method_registers.blit_engine_clip_height() != method_registers.blit_engine_input_height() || + method_registers.blit_engine_clip_x() > 0 || + method_registers.blit_engine_clip_y() > 0 || + convert_w != out_w || convert_h != out_h; bool need_convert = out_format != in_format || scale_x != 1.0 || scale_y != 1.0; @@ -549,7 +533,7 @@ namespace rsx } } - if (method_registers[NV3089_SET_CONTEXT_SURFACE] != CELL_GCM_CONTEXT_SWIZZLE2D) + if (method_registers.blit_engine_context_surface() != blit_engine::context_surface::swizzle2d) { if (need_convert || need_clip) { @@ -558,7 +542,7 @@ namespace rsx if (need_convert) { convert_scale_image(temp1, out_format, convert_w, convert_h, out_pitch, - pixels_src, in_format, in_w, in_h, in_pitch, slice_h, in_inter ? true : false); + pixels_src, in_format, in_w, in_h, in_pitch, slice_h, in_inter == blit_engine::transfer_interpolator::foh); clip_image(pixels_dst + out_offset, temp1.get(), clip_x, clip_y, clip_w, clip_h, out_bpp, out_pitch, out_pitch); } @@ -570,7 +554,7 @@ namespace rsx else { convert_scale_image(pixels_dst + out_offset, out_format, out_w, out_h, out_pitch, - pixels_src, in_format, in_w, in_h, in_pitch, slice_h, in_inter ? true : false); + pixels_src, in_format, in_w, in_h, in_pitch, slice_h, in_inter == blit_engine::transfer_interpolator::foh); } } else @@ -600,7 +584,7 @@ namespace rsx if (need_convert) { convert_scale_image(temp1, out_format, convert_w, convert_h, out_pitch, - pixels_src, in_format, in_w, in_h, in_pitch, slice_h, in_inter ? true : false); + pixels_src, in_format, in_w, in_h, in_pitch, slice_h, in_inter == blit_engine::transfer_interpolator::foh); clip_image(temp2, temp1.get(), clip_x, clip_y, clip_w, clip_h, out_bpp, out_pitch, out_pitch); } @@ -612,14 +596,14 @@ namespace rsx else { convert_scale_image(temp2, out_format, out_w, out_h, out_pitch, - pixels_src, in_format, in_w, in_h, in_pitch, clip_h, in_inter ? true : false); + pixels_src, in_format, in_w, in_h, in_pitch, clip_h, in_inter == blit_engine::transfer_interpolator::foh); } pixels_src = temp2.get(); } - u8 sw_width_log2 = method_registers[NV309E_SET_FORMAT] >> 16; - u8 sw_height_log2 = method_registers[NV309E_SET_FORMAT] >> 24; + u8 sw_width_log2 = method_registers.nv309e_sw_width_log2(); + u8 sw_height_log2 = method_registers.nv309e_sw_height_log2(); // 0 indicates height of 1 pixel sw_height_log2 = sw_height_log2 == 0 ? 1 : sw_height_log2; @@ -676,12 +660,12 @@ namespace rsx { force_inline void buffer_notify(u32 arg) { - u32 in_pitch = method_registers[NV0039_PITCH_IN]; - u32 out_pitch = method_registers[NV0039_PITCH_OUT]; - const u32 line_length = method_registers[NV0039_LINE_LENGTH_IN]; - const u32 line_count = method_registers[NV0039_LINE_COUNT]; - const u8 out_format = method_registers[NV0039_FORMAT] >> 8; - const u8 in_format = method_registers[NV0039_FORMAT]; + u32 in_pitch = method_registers.nv0039_input_pitch(); + u32 out_pitch = method_registers.nv0039_output_pitch(); + const u32 line_length = method_registers.nv0039_line_length(); + const u32 line_count = method_registers.nv0039_line_count(); + const u8 out_format = method_registers.nv0039_output_format(); + const u8 in_format = method_registers.nv0039_input_format(); const u32 notify = arg; // The existing GCM commands use only the value 0x1 for inFormat and outFormat @@ -700,11 +684,11 @@ namespace rsx out_pitch = line_length; } - u32 src_offset = method_registers[NV0039_OFFSET_IN]; - u32 src_dma = method_registers[NV0039_SET_CONTEXT_DMA_BUFFER_IN]; + u32 src_offset = method_registers.nv0039_input_offset(); + u32 src_dma = method_registers.nv0039_input_location(); - u32 dst_offset = method_registers[NV0039_OFFSET_OUT]; - u32 dst_dma = method_registers[NV0039_SET_CONTEXT_DMA_BUFFER_OUT]; + u32 dst_offset = method_registers.nv0039_output_offset(); + u32 dst_dma = method_registers.nv0039_output_location(); u8 *dst = (u8*)vm::base(get_address(dst_offset, dst_dma)); const u8 *src = (u8*)vm::base(get_address(src_offset, src_dma)); diff --git a/rpcs3/Emu/RSX/rsx_methods.h b/rpcs3/Emu/RSX/rsx_methods.h index ef34418dee..cd9b4aa495 100644 --- a/rpcs3/Emu/RSX/rsx_methods.h +++ b/rpcs3/Emu/RSX/rsx_methods.h @@ -1,5 +1,13 @@ #pragma once +#include +#include + +#include "GCM.h" +#include "RSXTexture.h" +#include "rsx_vertex_data.h" +#include "Utilities/geometry.h" + namespace rsx { //TODO @@ -63,7 +71,1111 @@ namespace rsx } }; + template + std::array fill_array(Args&& arg, std::index_sequence seq) + { + return{ T(N, std::forward(arg))... }; + } + + struct rsx_state + { + private: + std::array registers; + + public: + std::array fragment_textures; + std::array vertex_textures; + + std::array transform_program; + + std::unordered_map> transform_constants; + + /** + * RSX can sources vertex attributes from 2 places: + * - Immediate values passed by NV4097_SET_VERTEX_DATA*_M + ARRAY_ID write. + * For a given ARRAY_ID the last command of this type defines the actual type of the immediate value. + * Since there can be only a single value per ARRAY_ID passed this way, all vertex in the draw call + * shares it. + * - Vertex array values passed by offset/stride/size/format description. + * + * A given ARRAY_ID can have both an immediate value and a vertex array enabled at the same time + * (See After Burner Climax intro cutscene). In such case the vertex array has precedence over the + * immediate value. As soon as the vertex array is disabled (size set to 0) the immediate value + * must be used if the vertex attrib mask request it. + * + * Note that behavior when both vertex array and immediate value system are disabled but vertex attrib mask + * request inputs is unknow. + */ + std::array register_vertex_info; + 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>())) + { + + } + + u32& operator[](size_t idx) + { + return registers[idx]; + } + + const u32& operator[](size_t idx) const + { + return registers[idx]; + } + + void reset() + { + //setup method registers + std::memset(registers.data(), 0, registers.size() * sizeof(u32)); + + 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; + + registers[NV4097_SET_ALPHA_FUNC] = CELL_GCM_ALWAYS; + registers[NV4097_SET_ALPHA_REF] = 0; + + registers[NV4097_SET_BLEND_FUNC_SFACTOR] = (CELL_GCM_ONE << 16) | CELL_GCM_ONE; + registers[NV4097_SET_BLEND_FUNC_DFACTOR] = (CELL_GCM_ZERO << 16) | CELL_GCM_ZERO; + registers[NV4097_SET_BLEND_COLOR] = 0; + registers[NV4097_SET_BLEND_COLOR2] = 0; + registers[NV4097_SET_BLEND_EQUATION] = (CELL_GCM_FUNC_ADD << 16) | CELL_GCM_FUNC_ADD; + + 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; + + 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; + + registers[NV4097_SET_SHADE_MODE] = CELL_GCM_SMOOTH; + + registers[NV4097_SET_LOGIC_OP] = CELL_GCM_COPY; + + (f32&)registers[NV4097_SET_DEPTH_BOUNDS_MIN] = 0.f; + (f32&)registers[NV4097_SET_DEPTH_BOUNDS_MAX] = 1.f; + + (f32&)registers[NV4097_SET_CLIP_MIN] = 0.f; + (f32&)registers[NV4097_SET_CLIP_MAX] = 1.f; + + registers[NV4097_SET_LINE_WIDTH] = 1 << 3; + + // These defaults were found using After Burner Climax (which never set fog mode despite using fog input) + 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.; + + registers[NV4097_SET_DEPTH_FUNC] = CELL_GCM_LESS; + registers[NV4097_SET_DEPTH_MASK] = CELL_GCM_TRUE; + (f32&)registers[NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR] = 0.f; + (f32&)registers[NV4097_SET_POLYGON_OFFSET_BIAS] = 0.f; + registers[NV4097_SET_FRONT_POLYGON_MODE] = CELL_GCM_POLYGON_MODE_FILL; + registers[NV4097_SET_BACK_POLYGON_MODE] = CELL_GCM_POLYGON_MODE_FILL; + registers[NV4097_SET_CULL_FACE] = CELL_GCM_BACK; + registers[NV4097_SET_FRONT_FACE] = CELL_GCM_CCW; + registers[NV4097_SET_RESTART_INDEX] = -1; + + registers[NV4097_SET_CLEAR_RECT_HORIZONTAL] = (4096 << 16) | 0; + registers[NV4097_SET_CLEAR_RECT_VERTICAL] = (4096 << 16) | 0; + + registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffffff; + + 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; + + // 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); + } + } + + u16 viewport_width() const + { + return registers[NV4097_SET_VIEWPORT_HORIZONTAL] >> 16; + } + + u16 viewport_origin_x() const + { + return registers[NV4097_SET_VIEWPORT_HORIZONTAL] & 0xffff; + } + + u16 viewport_height() const + { + return registers[NV4097_SET_VIEWPORT_VERTICAL] >> 16; + } + + u16 viewport_origin_y() const + { + return registers[NV4097_SET_VIEWPORT_VERTICAL] & 0xffff; + } + + u16 scissor_origin_x() const + { + return registers[NV4097_SET_SCISSOR_HORIZONTAL] & 0xffff; + } + + u16 scissor_width() const + { + return registers[NV4097_SET_SCISSOR_HORIZONTAL] >> 16; + } + + u16 scissor_origin_y() const + { + return registers[NV4097_SET_SCISSOR_VERTICAL] & 0xffff; + } + + u16 scissor_height() const + { + return registers[NV4097_SET_SCISSOR_VERTICAL] >> 16; + } + + rsx::window_origin shader_window_origin() const + { + return rsx::to_window_origin((registers[NV4097_SET_SHADER_WINDOW] >> 12) & 0xf); + } + + rsx::window_pixel_center shader_window_pixel() const + { + return rsx::to_window_pixel_center((registers[NV4097_SET_SHADER_WINDOW] >> 16) & 0xf); + } + + u16 shader_window_height() const + { + return registers[NV4097_SET_SHADER_WINDOW] & 0xfff; + } + + u32 shader_window_offset_x() const + { + return registers[NV4097_SET_WINDOW_OFFSET] & 0xffff; + } + + u32 shader_window_offset_y() const + { + return registers[NV4097_SET_WINDOW_OFFSET] >> 16; + } + + bool depth_test_enabled() const + { + return !!registers[NV4097_SET_DEPTH_TEST_ENABLE]; + } + + bool depth_write_enabled() const + { + return !!registers[NV4097_SET_DEPTH_MASK]; + } + + bool alpha_test_enabled() const + { + return !!registers[NV4097_SET_ALPHA_TEST_ENABLE]; + } + + bool stencil_test_enabled() const + { + return !!registers[NV4097_SET_STENCIL_TEST_ENABLE]; + } + + bool restart_index_enabled() const + { + return !!registers[NV4097_SET_RESTART_INDEX_ENABLE]; + } + + u32 restart_index() const + { + return registers[NV4097_SET_RESTART_INDEX]; + } + + u32 z_clear_value() const + { + return registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] >> 8; + } + + u8 stencil_clear_value() const + { + return registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] & 0xff; + } + + f32 fog_params_0() const + { + return (f32&)registers[NV4097_SET_FOG_PARAMS]; + } + + 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]; + } + + u8 index_array_location() const + { + return registers[NV4097_SET_INDEX_ARRAY_DMA] & 0xf; + } + + u32 vertex_data_base_index() const + { + return registers[NV4097_SET_VERTEX_DATA_BASE_INDEX]; + } + + u32 shader_program_address() const + { + return registers[NV4097_SET_SHADER_PROGRAM]; + } + + u32 transform_program_start() const + { + return registers[NV4097_SET_TRANSFORM_PROGRAM_START]; + } + + primitive_type primitive_mode() const + { + return to_primitive_type(registers[NV4097_SET_BEGIN_END]); + } + + u32 semaphore_offset_406e() const + { + return registers[NV406E_SEMAPHORE_OFFSET]; + } + + u32 semaphore_offset_4097() const + { + return registers[NV4097_SET_SEMAPHORE_OFFSET]; + } + + blit_engine::context_dma context_dma_report() const + { + return blit_engine::to_context_dma(registers[NV4097_SET_CONTEXT_DMA_REPORT]); + } + + blit_engine::transfer_operation blit_engine_operation() const + { + return blit_engine::to_transfer_operation(registers[NV3089_SET_OPERATION]); + } + + /// TODO: find the purpose vs in/out equivalents + u16 blit_engine_clip_x() const + { + return registers[NV3089_CLIP_POINT] & 0xffff; + } + + u16 blit_engine_clip_y() const + { + return registers[NV3089_CLIP_POINT] >> 16; + } + + u16 blit_engine_clip_width() const + { + return registers[NV3089_CLIP_SIZE] & 0xffff; + } + + u16 blit_engine_clip_height() const + { + return registers[NV3089_CLIP_SIZE] >> 16; + } + + u16 blit_engine_output_x() const + { + return registers[NV3089_IMAGE_OUT_POINT] & 0xffff; + } + + u16 blit_engine_output_y() const + { + return registers[NV3089_IMAGE_OUT_POINT] >> 16; + } + + u16 blit_engine_output_width() const + { + return registers[NV3089_IMAGE_OUT_SIZE] & 0xffff; + } + + u16 blit_engine_output_height() const + { + return registers[NV3089_IMAGE_OUT_SIZE] >> 16; + } + + // there is no x/y ? + u16 blit_engine_input_width() const + { + return registers[NV3089_IMAGE_IN_SIZE] & 0xffff; + } + + u16 blit_engine_input_height() const + { + return registers[NV3089_IMAGE_IN_SIZE] >> 16; + } + + u16 blit_engine_input_pitch() const + { + return registers[NV3089_IMAGE_IN_FORMAT] & 0xffff; + } + + blit_engine::transfer_origin blit_engine_input_origin() const + { + return blit_engine::to_transfer_origin((registers[NV3089_IMAGE_IN_FORMAT] >> 16) & 0xff); + } + + blit_engine::transfer_interpolator blit_engine_input_inter() const + { + return blit_engine::to_transfer_interpolator((registers[NV3089_IMAGE_IN_FORMAT] >> 24) & 0xff); + } + + blit_engine::transfer_source_format blit_engine_src_color_format() const + { + return blit_engine::to_transfer_source_format(registers[NV3089_SET_COLOR_FORMAT]); + } + + // ??? + f32 blit_engine_in_x() const + { + return (registers[NV3089_IMAGE_IN] & 0xffff) / 16.f; + } + + // ??? + f32 blit_engine_in_y() const + { + return (registers[NV3089_IMAGE_IN] >> 16) / 16.f; + } + + u32 blit_engine_input_offset() const + { + return registers[NV3089_IMAGE_IN_OFFSET]; + } + + u32 blit_engine_input_location() const + { + return registers[NV3089_SET_CONTEXT_DMA_IMAGE]; + } + + blit_engine::context_surface blit_engine_context_surface() const + { + return blit_engine::to_context_surface(registers[NV3089_SET_CONTEXT_SURFACE]); + } + + u32 blit_engine_output_location_nv3062() const + { + return registers[NV3062_SET_CONTEXT_DMA_IMAGE_DESTIN]; + } + + u32 blit_engine_output_offset_nv3062() const + { + return registers[NV3062_SET_OFFSET_DESTIN]; + } + + blit_engine::transfer_destination_format blit_engine_nv3062_color_format() const + { + return rsx::blit_engine::to_transfer_destination_format(registers[NV3062_SET_COLOR_FORMAT]); + } + + u16 blit_engine_output_alignment_nv3062() const + { + return registers[NV3062_SET_PITCH] & 0xffff; + } + + u16 blit_engine_output_pitch_nv3062() const + { + return registers[NV3062_SET_PITCH] >> 16; + } + + u32 blit_engine_nv309E_location() const + { + return registers[NV309E_SET_CONTEXT_DMA_IMAGE]; + } + + u32 blit_engine_nv309E_offset() const + { + return registers[NV309E_SET_OFFSET]; + } + + blit_engine::transfer_destination_format blit_engine_output_format_nv309E() const + { + return rsx::blit_engine::to_transfer_destination_format(registers[NV309E_SET_FORMAT]); + } + + u32 blit_engine_ds_dx() const + { + return registers[NV3089_DS_DX]; + } + + u32 blit_engine_dt_dy() const + { + return registers[NV3089_DT_DY]; + } + + u8 nv309e_sw_width_log2() const + { + return (registers[NV309E_SET_FORMAT] >> 16) & 0xff; + } + + u8 nv309e_sw_height_log2() const + { + return (registers[NV309E_SET_FORMAT] >> 24) & 0xff; + } + + u32 nv0039_input_pitch() const + { + return registers[NV0039_PITCH_IN]; + } + + u32 nv0039_output_pitch() const + { + return registers[NV0039_PITCH_OUT]; + } + + u32 nv0039_line_length() const + { + return registers[NV0039_LINE_LENGTH_IN]; + } + + u32 nv0039_line_count() const + { + return registers[NV0039_LINE_COUNT]; + } + + u8 nv0039_output_format() const + { + return (registers[NV0039_FORMAT] >> 8) & 0xff; + } + + u8 nv0039_input_format() const + { + return registers[NV0039_FORMAT] & 0xff; + } + + u32 nv0039_output_offset() const + { + return registers[NV0039_OFFSET_OUT]; + } + + u32 nv0039_output_location() + { + return registers[NV0039_SET_CONTEXT_DMA_BUFFER_OUT]; + } + + u32 nv0039_input_offset() const + { + return registers[NV0039_OFFSET_IN]; + } + + 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; + } + + u16 nv308a_x() const + { + return registers[NV308A_POINT] & 0xffff; + } + + u16 nv308a_y() const + { + return registers[NV308A_POINT] >> 16; + } + }; + using rsx_method_t = void(*)(class thread*, u32); - extern u32 method_registers[0x10000 >> 2]; + extern rsx_state method_registers; extern rsx_method_t methods[0x10000 >> 2]; } diff --git a/rpcs3/Emu/RSX/rsx_utils.cpp b/rpcs3/Emu/RSX/rsx_utils.cpp index bd52dfc60b..af68d725c2 100644 --- a/rpcs3/Emu/RSX/rsx_utils.cpp +++ b/rpcs3/Emu/RSX/rsx_utils.cpp @@ -70,14 +70,12 @@ namespace rsx void fill_window_matrix(void *dest, bool transpose) { - u32 shader_window = method_registers[NV4097_SET_SHADER_WINDOW]; + u16 height = method_registers.shader_window_height(); + window_origin origin = method_registers.shader_window_origin(); + window_pixel_center pixelCenter = method_registers.shader_window_pixel(); - u16 height = shader_window & 0xfff; - window_origin origin = to_window_origin((shader_window >> 12) & 0xf); - window_pixel_center pixelCenter = to_window_pixel_center(shader_window >> 16); - - f32 offset_x = f32(method_registers[NV4097_SET_WINDOW_OFFSET] & 0xffff); - f32 offset_y = f32(method_registers[NV4097_SET_WINDOW_OFFSET] >> 16); + f32 offset_x = f32(method_registers.shader_window_offset_x()); + f32 offset_y = f32(method_registers.shader_window_offset_y()); f32 scale_y = 1.0; if (origin == window_origin::bottom) @@ -97,13 +95,13 @@ namespace rsx void fill_viewport_matrix(void *buffer, bool transpose) { - f32 offset_x = (f32&)method_registers[NV4097_SET_VIEWPORT_OFFSET + 0]; - f32 offset_y = (f32&)method_registers[NV4097_SET_VIEWPORT_OFFSET + 1]; - f32 offset_z = (f32&)method_registers[NV4097_SET_VIEWPORT_OFFSET + 2]; + f32 offset_x = method_registers.viewport_offset_x(); + f32 offset_y = method_registers.viewport_offset_y(); + f32 offset_z = method_registers.viewport_offset_z(); - f32 scale_x = (f32&)method_registers[NV4097_SET_VIEWPORT_SCALE + 0]; - f32 scale_y = (f32&)method_registers[NV4097_SET_VIEWPORT_SCALE + 1]; - f32 scale_z = (f32&)method_registers[NV4097_SET_VIEWPORT_SCALE + 2]; + f32 scale_x = method_registers.viewport_scale_x(); + f32 scale_y = method_registers.viewport_scale_y(); + f32 scale_z = method_registers.viewport_scale_z(); fill_scale_offset_matrix(buffer, transpose, offset_x, offset_y, offset_z, scale_x, scale_y, scale_z); } diff --git a/rpcs3/Emu/RSX/rsx_vertex_data.h b/rpcs3/Emu/RSX/rsx_vertex_data.h new file mode 100644 index 0000000000..2b6cf55e07 --- /dev/null +++ b/rpcs3/Emu/RSX/rsx_vertex_data.h @@ -0,0 +1,40 @@ +#pragma once + +#include "GCM.h" +#include "Utilities/types.h" + +namespace rsx +{ + +struct data_array_format_info +{ +private: + u8 index; + std::array ®isters; +public: + u16 frequency = 0; + u8 stride = 0; + u8 size = 0; + vertex_base_type type = vertex_base_type::f; + + + data_array_format_info(u8 idx, std::array &r) : index(idx), registers(r) + {} + + data_array_format_info() = delete; + + void unpack_array(u32 data_array_format) + { + frequency = data_array_format >> 16; + stride = (data_array_format >> 8) & 0xff; + size = (data_array_format >> 4) & 0xf; + type = to_vertex_base_type(data_array_format & 0xf); + } + + u32 offset() const + { + return registers[NV4097_SET_VERTEX_DATA_ARRAY_OFFSET + index]; + } +}; + +} diff --git a/rpcs3/Gui/RSXDebugger.cpp b/rpcs3/Gui/RSXDebugger.cpp index a615edd205..c705cb12fe 100644 --- a/rpcs3/Gui/RSXDebugger.cpp +++ b/rpcs3/Gui/RSXDebugger.cpp @@ -370,13 +370,13 @@ void RSXDebugger::OnClickBuffer(wxMouseEvent& event) if (event.GetId() == p_buffer_stencil->GetId()) display_buffer(this, stencil_img); if (event.GetId() == p_buffer_tex->GetId()) { - u8 location = render->textures[m_cur_texture].location(); +/* u8 location = render->textures[m_cur_texture].location(); if(location <= 1 && vm::check_addr(rsx::get_address(render->textures[m_cur_texture].offset(), location)) && render->textures[m_cur_texture].width() && render->textures[m_cur_texture].height()) MemoryViewerPanel::ShowImage(this, rsx::get_address(render->textures[m_cur_texture].offset(), location), 1, render->textures[m_cur_texture].width(), - render->textures[m_cur_texture].height(), false); + render->textures[m_cur_texture].height(), false);*/ } #undef SHOW_BUFFER @@ -725,7 +725,7 @@ void RSXDebugger::GetBuffers() } // Draw Texture - if(!render->textures[m_cur_texture].enabled()) +/* if(!render->textures[m_cur_texture].enabled()) return; u32 offset = render->textures[m_cur_texture].offset(); @@ -752,7 +752,7 @@ void RSXDebugger::GetBuffers() wxImage img(width, height, buffer); wxClientDC dc_canvas(p_buffer_tex); - dc_canvas.DrawBitmap(img.Scale(m_text_width, m_text_height), 0, 0, false); + dc_canvas.DrawBitmap(img.Scale(m_text_width, m_text_height), 0, 0, false);*/ } void RSXDebugger::GetFlags() @@ -823,7 +823,7 @@ void RSXDebugger::GetTexture() for(uint i=0; itextures[i].enabled()) +/* if(render->textures[i].enabled()) { m_list_texture->InsertItem(i, wxString::Format("%d", i)); u8 location = render->textures[i].location(); @@ -848,7 +848,7 @@ void RSXDebugger::GetTexture() render->textures[i].height())); m_list_texture->SetItemBackgroundColour(i, wxColour(m_cur_texture == i ? "Wheat" : "White")); - } + }*/ } } diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 7a42722c77..63889b31ae 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 95e9c82e6f..b51c8967b4 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1687,5 +1687,8 @@ Utilities + + Emu\GPU\RSX + \ No newline at end of file