From eae1ac655806ff4ab0f62709be1f2a6c8f57e8ad Mon Sep 17 00:00:00 2001 From: kd-11 Date: Tue, 3 Jan 2023 20:31:40 +0300 Subject: [PATCH] refactor: Fix build --- rpcs3/Emu/RSX/Common/BufferUtils.cpp | 4 -- rpcs3/Emu/RSX/Common/expected.hpp | 33 +++++++++++--- rpcs3/Emu/RSX/gcm_enums.h | 66 ++++++++++++++-------------- rpcs3/Emu/RSX/rsx_decode.h | 15 +++---- rpcs3/Emu/RSX/rsx_methods.cpp | 41 ++++++++--------- rpcs3/Emu/RSX/rsx_methods.h | 6 +-- 6 files changed, 89 insertions(+), 76 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/BufferUtils.cpp b/rpcs3/Emu/RSX/Common/BufferUtils.cpp index 670f6d0ac6..3b5bd61d2c 100644 --- a/rpcs3/Emu/RSX/Common/BufferUtils.cpp +++ b/rpcs3/Emu/RSX/Common/BufferUtils.cpp @@ -571,8 +571,6 @@ bool is_primitive_native(rsx::primitive_type draw_mode) case rsx::primitive_type::triangle_fan: case rsx::primitive_type::quads: return false; - case rsx::primitive_type::invalid: - break; } fmt::throw_exception("Wrong primitive type"); @@ -663,8 +661,6 @@ void write_index_array_for_non_indexed_non_native_primitive_to_buffer(char* dst, case rsx::primitive_type::triangles: case rsx::primitive_type::triangle_strip: fmt::throw_exception("Native primitive type doesn't require expansion"); - case rsx::primitive_type::invalid: - break; } fmt::throw_exception("Tried to load invalid primitive type"); diff --git a/rpcs3/Emu/RSX/Common/expected.hpp b/rpcs3/Emu/RSX/Common/expected.hpp index eda22dee8a..0f0844d0c0 100644 --- a/rpcs3/Emu/RSX/Common/expected.hpp +++ b/rpcs3/Emu/RSX/Common/expected.hpp @@ -1,13 +1,14 @@ #pragma once #include #include +#include namespace rsx { template concept ErrorType = requires (E& e) { - { e.empty() } -> bool; + { e.empty() } -> std::same_as; }; template @@ -17,24 +18,42 @@ namespace rsx E error{}; public: - expected(const T& value_) + [[ nodiscard ]] expected(const T& value_) : value(value_) {} - expected(const E& error_) + [[ nodiscard ]] expected(const E& error_) : error(error_) - {} + { + ensure(!error.empty()); + } operator T() const { - ensure(!error); + ensure(error.empty()); return value; } - std::enable_if> + T operator *() const + { + ensure(error.empty()); + return value; + } + + template>> operator bool() const { - return !error; + return error.empty(); + } + + operator std::pair() const + { + return { value, error }; + } + + bool operator == (const T& other) const + { + return error.empty() && value == other; } }; } diff --git a/rpcs3/Emu/RSX/gcm_enums.h b/rpcs3/Emu/RSX/gcm_enums.h index a8bfb91779..b1846317f2 100644 --- a/rpcs3/Emu/RSX/gcm_enums.h +++ b/rpcs3/Emu/RSX/gcm_enums.h @@ -2,6 +2,7 @@ #include "util/types.hpp" #include "Common/expected.hpp" +#include "Utilities/StrFmt.h" namespace gcm { @@ -975,8 +976,8 @@ namespace rsx return fmt::format("Enum out of range 0x%x", value); } - template - expected gcm_enum_cast(u32 value, u32 allowed[N]) + template + expected gcm_enum_cast(u32 value, std::initializer_list allowed) { for (const auto v : allowed) { @@ -989,8 +990,8 @@ namespace rsx return fmt::format("Invalid enum value 0x%x", value); } - template - expected gcm_enum_cast(u32 value, u32 allowed[2][N]) + template + expected gcm_enum_cast(u32 value, std::initializer_list allowed) { for (const auto& range : allowed) { @@ -1021,7 +1022,7 @@ namespace rsx vertex_base_type, RSX_VERTEX_BASE_TYPE_SNORM16, RSX_VERTEX_BASE_TYPE_INT8>(in) - : vertex_base_type::ub256; + : expected(vertex_base_type::ub256); } enum class index_array_type : u8 @@ -1064,7 +1065,7 @@ namespace rsx static inline auto to_surface_target(u32 in) { - gcm_enum_cast(in, { + return gcm_enum_cast(in, { CELL_GCM_SURFACE_TARGET_0, CELL_GCM_SURFACE_TARGET_MRT1, CELL_GCM_SURFACE_TARGET_NONE, @@ -1111,6 +1112,7 @@ namespace rsx enum class surface_raster_type : u8 { + undefined = CELL_GCM_ZERO, linear = CELL_GCM_SURFACE_PITCH, swizzle = CELL_GCM_SURFACE_SWIZZLE, }; @@ -1125,11 +1127,11 @@ namespace rsx static inline auto to_surface_antialiasing(u32 in) { - return gcm_enum_cast< - surface_antialiasing, - CELL_GCM_SURFACE_DIAGONAL_CENTERED_2, - CELL_GCM_SURFACE_SQUARE_ROTATED_4, - CELL_GCM_SURFACE_CENTER_1> + return gcm_enum_cast(in, + { + { CELL_GCM_SURFACE_CENTER_1, CELL_GCM_SURFACE_CENTER_1 }, + { CELL_GCM_SURFACE_DIAGONAL_CENTERED_2, CELL_GCM_SURFACE_SQUARE_ROTATED_4 } + }); } enum class surface_color_format : u8 @@ -1137,7 +1139,7 @@ namespace rsx x1r5g5b5_z1r5g5b5 = CELL_GCM_SURFACE_X1R5G5B5_Z1R5G5B5, x1r5g5b5_o1r5g5b5 = CELL_GCM_SURFACE_X1R5G5B5_O1R5G5B5, r5g6b5 = CELL_GCM_SURFACE_R5G6B5, - x8r8g8b8_z8r8g8b8 = CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8 + x8r8g8b8_z8r8g8b8 = CELL_GCM_SURFACE_X8R8G8B8_Z8R8G8B8, x8r8g8b8_o8r8g8b8 = CELL_GCM_SURFACE_X8R8G8B8_O8R8G8B8, a8r8g8b8 = CELL_GCM_SURFACE_A8R8G8B8, b8 = CELL_GCM_SURFACE_B8, @@ -1160,7 +1162,7 @@ namespace rsx enum class window_origin : u8 { - top = CELL_GCM_WINDOW_ORIGIN_TOP + top = CELL_GCM_WINDOW_ORIGIN_TOP, bottom = CELL_GCM_WINDOW_ORIGIN_BOTTOM }; @@ -1186,7 +1188,7 @@ namespace rsx CELL_GCM_WINDOW_PIXEL_CENTER_INTEGER>(in); } - enum class comparison_function : u8 + enum class comparison_function : u16 { never = CELL_GCM_NEVER, less = CELL_GCM_LESS, @@ -1203,15 +1205,15 @@ namespace rsx return gcm_enum_cast< comparison_function, CELL_GCM_NEVER, - CELL_GCM_ALWAYS>(in & 0xFF); + CELL_GCM_ALWAYS>(in | 0x200); } - enum class fog_mode : u8 + enum class fog_mode : u16 { linear = CELL_GCM_FOG_MODE_LINEAR, exponential = CELL_GCM_FOG_MODE_EXP, exponential2 = CELL_GCM_FOG_MODE_EXP2, - exponential_abs = CELL_GCM_FOG_MODE_EXP_ABS + exponential_abs = CELL_GCM_FOG_MODE_EXP_ABS, exponential2_abs = CELL_GCM_FOG_MODE_EXP2_ABS, linear_abs = CELL_GCM_FOG_MODE_LINEAR_ABS }; @@ -1220,7 +1222,7 @@ namespace rsx { if (in == CELL_GCM_FOG_MODE_LINEAR) { - return fog_mode::linear; + return expected(fog_mode::linear); } return gcm_enum_cast< @@ -1320,10 +1322,10 @@ namespace rsx static inline auto to_texture_magnify_filter(u32 in) { - return gcm_enum_cast(value, { CELL_GCM_TEXTURE_LINEAR, CELL_GCM_TEXTURE_NEAREST, CELL_GCM_TEXTURE_CONVOLUTION_MAG}); + return gcm_enum_cast(in, { CELL_GCM_TEXTURE_LINEAR, CELL_GCM_TEXTURE_NEAREST, CELL_GCM_TEXTURE_CONVOLUTION_MAG }); } - enum class stencil_op : u8 + enum class stencil_op : u16 { keep = CELL_GCM_KEEP, zero = CELL_GCM_ZERO, @@ -1345,11 +1347,11 @@ namespace rsx }); } - enum class blend_equation : u8 + enum class blend_equation : u16 { add = CELL_GCM_FUNC_ADD, - min = CELL_GCM_FUNC_MIN, - max = CELL_GCM_FUNC_MAX, + min = CELL_GCM_MIN, + max = CELL_GCM_MAX, subtract = CELL_GCM_FUNC_SUBTRACT, reverse_subtract = CELL_GCM_FUNC_REVERSE_SUBTRACT, reverse_subtract_signed = CELL_GCM_FUNC_REVERSE_SUBTRACT_SIGNED, @@ -1366,7 +1368,7 @@ namespace rsx }); } - enum class blend_factor : u8 + enum class blend_factor : u16 { zero = CELL_GCM_ZERO, one = CELL_GCM_ONE, @@ -1391,10 +1393,10 @@ namespace rsx { { CELL_GCM_SRC_COLOR, CELL_GCM_ONE_MINUS_CONSTANT_ALPHA }, { CELL_GCM_ZERO, CELL_GCM_ONE } - }) + }); } - enum class logic_op : u8 + enum class logic_op : u16 { logic_clear = CELL_GCM_CLEAR, logic_and = CELL_GCM_AND, @@ -1422,7 +1424,7 @@ namespace rsx CELL_GCM_SET>(in); } - enum class front_face : u8 + enum class front_face : u16 { cw = CELL_GCM_CW, /// clockwise ccw = CELL_GCM_CCW, /// counter clockwise @@ -1436,7 +1438,7 @@ namespace rsx CELL_GCM_CCW>(in); } - enum class cull_face : u32 + enum class cull_face : u16 { front = CELL_GCM_FRONT, back = CELL_GCM_BACK, @@ -1458,7 +1460,7 @@ namespace rsx CELL_GCM_USER_CLIP_PLANE_ENABLE_GE>(in); } - enum class shading_mode : u8 + enum class shading_mode : u16 { smooth = CELL_GCM_SMOOTH, flat = CELL_GCM_FLAT, @@ -1472,7 +1474,7 @@ namespace rsx CELL_GCM_SMOOTH>(in); } - enum class polygon_mode : u8 + enum class polygon_mode : u16 { point = CELL_GCM_POLYGON_MODE_POINT, line = CELL_GCM_POLYGON_MODE_LINE, @@ -1577,7 +1579,7 @@ namespace rsx }); } - enum class context_surface : u8 + enum class context_surface : u32 { surface2d = CELL_GCM_CONTEXT_SURFACE2D, swizzle2d = CELL_GCM_CONTEXT_SWIZZLE2D, @@ -1592,7 +1594,7 @@ namespace rsx }); } - enum class context_dma : u8 + enum class context_dma : u32 { to_memory_get_report = CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_LOCAL, report_location_main = CELL_GCM_CONTEXT_DMA_REPORT_LOCATION_MAIN, diff --git a/rpcs3/Emu/RSX/rsx_decode.h b/rpcs3/Emu/RSX/rsx_decode.h index 1e361d56e5..ece8785bd7 100644 --- a/rpcs3/Emu/RSX/rsx_decode.h +++ b/rpcs3/Emu/RSX/rsx_decode.h @@ -2812,7 +2812,7 @@ struct registers_decoder public: decoded_type(u32 value) : value(value) {} - blit_engine::transfer_source_format transfer_source_fmt() const + expected transfer_source_fmt() const { return blit_engine::to_transfer_source_format(value); } @@ -2820,7 +2820,7 @@ struct registers_decoder static std::string dump(const decoded_type& decoded) { - return fmt::format("NV3089: source fmt: %s", decoded.transfer_source_fmt()); + return fmt::format("NV3089: source fmt: %s", *decoded.transfer_source_fmt()); } }; @@ -2858,7 +2858,7 @@ struct registers_decoder public: decoded_type(u32 value) : value(value) {} - blit_engine::transfer_destination_format transfer_dest_fmt() const + expected transfer_dest_fmt() const { return blit_engine::to_transfer_destination_format(value); } @@ -2866,7 +2866,7 @@ struct registers_decoder static std::string dump(const decoded_type& decoded) { - return fmt::format("NV3062: output fmt: %s", decoded.transfer_dest_fmt()); + return fmt::format("NV3062: output fmt: %s", *decoded.transfer_dest_fmt()); } }; @@ -3741,10 +3741,9 @@ struct registers_decoder public: decoded_type(u32 value) : value(value) {} - blit_engine::transfer_destination_format format() const + expected format() const { - // Why truncate?? - return blit_engine::to_transfer_destination_format(static_cast(transfer_destination_fmt())); + return blit_engine::to_transfer_destination_format(transfer_destination_fmt()); } u8 sw_height_log2() const @@ -3760,7 +3759,7 @@ struct registers_decoder static std::string dump(const decoded_type& decoded) { - return fmt::format("NV309E: output fmt: %s log2-width: %u log2-height: %u", decoded.format(), + return fmt::format("NV309E: output fmt: %s log2-width: %u log2-height: %u", *decoded.format(), decoded.sw_width_log2(), decoded.sw_height_log2()); } }; diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index 87d1764944..f53890a804 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -593,9 +593,8 @@ namespace rsx // Ignore upper bits if (const u8 prim = static_cast(arg)) { - rsx::method_registers.current_draw_clause.reset(to_primitive_type(prim)); - - if (rsx::method_registers.current_draw_clause.primitive == rsx::primitive_type::invalid) + const auto primitive_type = to_primitive_type(prim); + if (!primitive_type) { rsxthr->in_begin_end = true; @@ -603,17 +602,18 @@ namespace rsx return; } + rsx::method_registers.current_draw_clause.reset(primitive_type); rsxthr->begin(); return; } - //Check if we have immediate mode vertex data in a driver-local buffer + // Check if we have immediate mode vertex data in a driver-local buffer if (rsx::method_registers.current_draw_clause.command == rsx::draw_command::none) { const u32 push_buffer_vertices_count = rsxthr->get_push_buffer_vertex_count(); const u32 push_buffer_index_count = rsxthr->get_push_buffer_index_count(); - //Need to set this flag since it overrides some register contents + // Need to set this flag since it overrides some register contents rsx::method_registers.current_draw_clause.is_immediate_draw = true; if (push_buffer_index_count) @@ -634,15 +634,6 @@ namespace rsx if (!rsx::method_registers.current_draw_clause.empty()) { - if (rsx::method_registers.current_draw_clause.primitive == rsx::primitive_type::invalid) - { - // Recover from invalid primitive only if draw clause is not empty - rsxthr->recover_fifo(); - - rsx_log.error("NV4097_SET_BEGIN_END aborted due to invalid primitive!"); - return; - } - rsx::method_registers.current_draw_clause.compile(); if (g_cfg.video.disable_video_output) @@ -1050,7 +1041,7 @@ namespace rsx // Skip "handled methods" rsx->fifo_ctrl->skip_methods(count - 1); - switch (method_registers.blit_engine_nv3062_color_format()) + switch (*method_registers.blit_engine_nv3062_color_format()) { case blit_engine::transfer_destination_format::a8r8g8b8: case blit_engine::transfer_destination_format::y32: @@ -1166,7 +1157,7 @@ namespace rsx const blit_engine::transfer_origin in_origin = method_registers.blit_engine_input_origin(); const 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(); + auto src_color_format = method_registers.blit_engine_src_color_format(); const f32 scale_x = method_registers.blit_engine_ds_dx(); const f32 scale_y = method_registers.blit_engine_dt_dy(); @@ -1214,7 +1205,7 @@ namespace rsx return; } - if (src_color_format == rsx::blit_engine::transfer_source_format::invalid) + if (!src_color_format) { rsx_log.error("NV3089_IMAGE_IN_SIZE: unknown src color format (0x%x)", method_registers.registers[NV3089_SET_COLOR_FORMAT]); rsx->recover_fifo(); @@ -1237,17 +1228,20 @@ namespace rsx { 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_alignment = method_registers.blit_engine_output_alignment_nv3062(); is_block_transfer = fcmp(scale_x, 1.f) && fcmp(scale_y, 1.f); - if (dst_color_format == rsx::blit_engine::transfer_destination_format::invalid) + if (auto dst_fmt = method_registers.blit_engine_nv3062_color_format(); !dst_fmt) { rsx_log.error("NV3089_IMAGE_IN_SIZE: unknown NV3062 dst color format (0x%x)", method_registers.registers[NV3062_SET_COLOR_FORMAT]); rsx->recover_fifo(); return; } + else + { + dst_color_format = dst_fmt; + } break; } @@ -1255,14 +1249,17 @@ namespace rsx { 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(); - if (dst_color_format == rsx::blit_engine::transfer_destination_format::invalid) + if (auto dst_fmt = method_registers.blit_engine_output_format_nv309E(); !dst_fmt) { rsx_log.error("NV3089_IMAGE_IN_SIZE: unknown NV309E dst color format (0x%x)", method_registers.registers[NV309E_SET_FORMAT]); rsx->recover_fifo(); return; } + else + { + dst_color_format = dst_fmt; + } break; } @@ -1395,7 +1392,7 @@ namespace rsx else { // TODO: Support more formats - fmt::throw_exception("NV3089_IMAGE_IN_SIZE: unknown src_color_format (%d)", static_cast(src_color_format)); + fmt::throw_exception("NV3089_IMAGE_IN_SIZE: unknown src_color_format (%d)", static_cast(*src_color_format)); } } diff --git a/rpcs3/Emu/RSX/rsx_methods.h b/rpcs3/Emu/RSX/rsx_methods.h index 88e7a02d87..3af74c5a20 100644 --- a/rpcs3/Emu/RSX/rsx_methods.h +++ b/rpcs3/Emu/RSX/rsx_methods.h @@ -1426,7 +1426,7 @@ namespace rsx return decode().transfer_interpolator(); } - blit_engine::transfer_source_format blit_engine_src_color_format() const + expected blit_engine_src_color_format() const { return decode().transfer_source_fmt(); } @@ -1468,7 +1468,7 @@ namespace rsx return decode().output_offset(); } - blit_engine::transfer_destination_format blit_engine_nv3062_color_format() const + expected blit_engine_nv3062_color_format() const { return decode().transfer_dest_fmt(); } @@ -1493,7 +1493,7 @@ namespace rsx return decode().offset(); } - blit_engine::transfer_destination_format blit_engine_output_format_nv309E() const + expected blit_engine_output_format_nv309E() const { return decode().format(); }