From 963a87fed511ac488b29fe5d33f694e806129838 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Tue, 31 Oct 2017 16:54:55 +0300 Subject: [PATCH] rsx: Critical fixes - Remove generic throws from the rsx pipeline. Stops the rsx thread from silently dying leaving the emulator in a hung state - Hackplement add_signed and reverse_subtract_signed blend modes --- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 132 ++++++++++++++++---------------- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 6 +- rpcs3/Emu/RSX/gcm_enums.cpp | 52 ++++++------- rpcs3/Emu/RSX/rsx_decode.h | 3 +- 4 files changed, 101 insertions(+), 92 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index ba6aa5fe8c..3b0c901642 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -51,7 +51,7 @@ namespace case rsx::comparison_function::greater_or_equal: return GL_GEQUAL; case rsx::comparison_function::always: return GL_ALWAYS; } - throw; + fmt::throw_exception("Unsupported comparison op 0x%X" HERE, (u32)op);; } GLenum stencil_op(rsx::stencil_op op) @@ -67,7 +67,7 @@ namespace case rsx::stencil_op::incr_wrap: return GL_INCR_WRAP; case rsx::stencil_op::decr_wrap: return GL_DECR_WRAP; } - throw; + fmt::throw_exception("Unsupported stencil op 0x%X" HERE, (u32)op); } GLenum blend_equation(rsx::blend_equation op) @@ -75,16 +75,20 @@ namespace switch (op) { // Note : maybe add is signed on gl + case rsx::blend_equation::add_signed: + LOG_TRACE(RSX, "blend equation add_signed used. Emulating using FUNC_ADD"); 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_signed: + LOG_TRACE(RSX, "blend equation reverse_subtract_signed used. Emulating using FUNC_REVERSE_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"; + case rsx::blend_equation::reverse_add_signed: + default: + LOG_ERROR(RSX, "Blend equation 0x%X is unimplemented!", (u32)op); + return GL_FUNC_ADD; } - throw; } GLenum blend_factor(rsx::blend_factor op) @@ -107,7 +111,7 @@ namespace 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; + fmt::throw_exception("Unsupported blend factor 0x%X" HERE, (u32)op); } GLenum logic_op(rsx::logic_op op) @@ -131,7 +135,7 @@ namespace case rsx::logic_op::logic_nand: return GL_NAND; case rsx::logic_op::logic_set: return GL_SET; } - throw; + fmt::throw_exception("Unsupported logic op 0x%X" HERE, (u32)op); } GLenum front_face(rsx::front_face op) @@ -143,7 +147,7 @@ namespace case rsx::front_face::cw: return (invert ? GL_CCW : GL_CW); case rsx::front_face::ccw: return (invert ? GL_CW : GL_CCW); } - throw; + fmt::throw_exception("Unsupported front face 0x%X" HERE, (u32)op); } GLenum cull_face(rsx::cull_face op) @@ -156,7 +160,7 @@ namespace case rsx::cull_face::back: return (invert ? GL_FRONT : GL_BACK); case rsx::cull_face::front_and_back: return GL_FRONT_AND_BACK; } - throw; + fmt::throw_exception("Unsupported cull face 0x%X" HERE, (u32)op); } } @@ -351,62 +355,62 @@ void GLGSRender::end() { std::chrono::time_point textures_start = steady_clock::now(); - std::lock_guard lock(m_sampler_mutex); + std::lock_guard lock(m_sampler_mutex); void* unused = nullptr; - - for (int i = 0; i < rsx::limits::fragment_textures_count; ++i) - { - if (m_samplers_dirty || m_textures_dirty[i]) - { - if (!fs_sampler_state[i]) - fs_sampler_state[i] = std::make_unique(); - - auto sampler_state = static_cast(fs_sampler_state[i].get()); - - if (rsx::method_registers.fragment_textures[i].enabled()) - { - glActiveTexture(GL_TEXTURE0 + i); - - *sampler_state = m_gl_texture_cache.upload_texture(unused, rsx::method_registers.fragment_textures[i], m_rtts); - m_gl_sampler_states[i].apply(rsx::method_registers.fragment_textures[i]); - - GLenum target = get_gl_target_for_texture(rsx::method_registers.fragment_textures[i]); - glBindTexture(target, sampler_state->image_handle); - } - else - { + + for (int i = 0; i < rsx::limits::fragment_textures_count; ++i) + { + if (m_samplers_dirty || m_textures_dirty[i]) + { + if (!fs_sampler_state[i]) + fs_sampler_state[i] = std::make_unique(); + + auto sampler_state = static_cast(fs_sampler_state[i].get()); + + if (rsx::method_registers.fragment_textures[i].enabled()) + { + glActiveTexture(GL_TEXTURE0 + i); + + *sampler_state = m_gl_texture_cache.upload_texture(unused, rsx::method_registers.fragment_textures[i], m_rtts); + m_gl_sampler_states[i].apply(rsx::method_registers.fragment_textures[i]); + + GLenum target = get_gl_target_for_texture(rsx::method_registers.fragment_textures[i]); + glBindTexture(target, sampler_state->image_handle); + } + else + { *sampler_state = {}; } - - m_textures_dirty[i] = false; - } - } - - for (int i = 0; i < rsx::limits::vertex_textures_count; ++i) - { - int texture_index = i + rsx::limits::fragment_textures_count; - - if (m_samplers_dirty || m_vertex_textures_dirty[i]) - { - if (!vs_sampler_state[i]) - vs_sampler_state[i] = std::make_unique(); - - auto sampler_state = static_cast(vs_sampler_state[i].get()); - - if (rsx::method_registers.vertex_textures[i].enabled()) - { - glActiveTexture(GL_TEXTURE0 + texture_index); - - *sampler_state = m_gl_texture_cache.upload_texture(unused, rsx::method_registers.vertex_textures[i], m_rtts); - glBindTexture(GL_TEXTURE_2D, static_cast(vs_sampler_state[i].get())->image_handle); - } - else - *sampler_state = {}; - - m_vertex_textures_dirty[i] = false; - } - } - + + m_textures_dirty[i] = false; + } + } + + for (int i = 0; i < rsx::limits::vertex_textures_count; ++i) + { + int texture_index = i + rsx::limits::fragment_textures_count; + + if (m_samplers_dirty || m_vertex_textures_dirty[i]) + { + if (!vs_sampler_state[i]) + vs_sampler_state[i] = std::make_unique(); + + auto sampler_state = static_cast(vs_sampler_state[i].get()); + + if (rsx::method_registers.vertex_textures[i].enabled()) + { + glActiveTexture(GL_TEXTURE0 + texture_index); + + *sampler_state = m_gl_texture_cache.upload_texture(unused, rsx::method_registers.vertex_textures[i], m_rtts); + glBindTexture(GL_TEXTURE_2D, static_cast(vs_sampler_state[i].get())->image_handle); + } + else + *sampler_state = {}; + + m_vertex_textures_dirty[i] = false; + } + } + m_samplers_dirty.store(false); std::chrono::time_point textures_end = steady_clock::now(); @@ -1062,7 +1066,7 @@ void GLGSRender::load_program(u32 vertex_base, u32 vertex_count) } m_transform_constants_dirty = false; -} +} void GLGSRender::flip(int buffer) { diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 9b237a2199..60c83a1743 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -230,9 +230,13 @@ namespace vk { switch (op) { + case rsx::blend_equation::add_signed: + LOG_TRACE(RSX, "blend equation add_signed used. Emulating using FUNC_ADD"); case rsx::blend_equation::add: - case rsx::blend_equation::add_signed: return VK_BLEND_OP_ADD; + return VK_BLEND_OP_ADD; case rsx::blend_equation::substract: return VK_BLEND_OP_SUBTRACT; + case rsx::blend_equation::reverse_substract_signed: + LOG_TRACE(RSX, "blend equation reverse_subtract_signed used. Emulating using FUNC_REVERSE_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; diff --git a/rpcs3/Emu/RSX/gcm_enums.cpp b/rpcs3/Emu/RSX/gcm_enums.cpp index cd667e6090..3614b271c7 100644 --- a/rpcs3/Emu/RSX/gcm_enums.cpp +++ b/rpcs3/Emu/RSX/gcm_enums.cpp @@ -157,7 +157,7 @@ namespace rsx case comparison_function::greater_or_equal: return "Greater_equal"; case comparison_function::always: return "Always"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(stencil_op op) @@ -173,7 +173,7 @@ namespace rsx case stencil_op::decr_wrap: return "Decr_wrap"; case stencil_op::invert: return "Invert"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(fog_mode op) @@ -187,7 +187,7 @@ namespace rsx case fog_mode::linear: return "linear"; case fog_mode::linear_abs: return "linear(abs)"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(logic_op op) @@ -211,7 +211,7 @@ namespace rsx case logic_op::logic_or_inverted: return "Or_inverted"; case logic_op::logic_nand: return "Nand"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(front_face op) @@ -221,7 +221,7 @@ namespace rsx case front_face::ccw: return "counter clock wise"; case front_face::cw: return "clock wise"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(cull_face op) @@ -232,7 +232,7 @@ namespace rsx case cull_face::front: return "front"; case cull_face::front_and_back: return "front and back"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(surface_target target) @@ -246,7 +246,7 @@ namespace rsx case surface_target::surfaces_a_b_c: return "surfaces A, B and C"; case surface_target::surfaces_a_b_c_d: return "surfaces A,B, C and D"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(primitive_type draw_mode) @@ -265,7 +265,7 @@ namespace rsx case primitive_type::quad_strip: return "Quad_strip"; case primitive_type::polygon: return "Polygon"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(blit_engine::transfer_operation op) @@ -279,7 +279,7 @@ namespace rsx case blit_engine::transfer_operation::srccopy_and: return "srccopy_and"; case blit_engine::transfer_operation::srccopy_premult: return "srccopy_premult"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(blit_engine::transfer_source_format op) @@ -300,7 +300,7 @@ namespace rsx case blit_engine::transfer_source_format::y8: return "y8"; case blit_engine::transfer_source_format::yb8cr8ya8cb8: return "yb8cr8ya8cb8"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(blit_engine::context_surface op) @@ -310,7 +310,7 @@ namespace rsx case blit_engine::context_surface::surface2d: return "surface 2d"; case blit_engine::context_surface::swizzle2d: return "swizzle 2d"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(blit_engine::transfer_destination_format op) @@ -321,7 +321,7 @@ namespace rsx case blit_engine::transfer_destination_format::r5g6b5: return "r5g6b5"; case blit_engine::transfer_destination_format::y32: return "y32"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } @@ -338,7 +338,7 @@ namespace rsx case blend_equation::reverse_add_signed: return "Reverse_add_signed"; case blend_equation::reverse_substract_signed: return "Reverse_substract_signed"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(blend_factor factor) @@ -361,7 +361,7 @@ namespace rsx case blend_factor::constant_alpha: return "const.a"; case blend_factor::one_minus_constant_alpha: return "(1 - const.a)"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(window_origin origin) @@ -371,7 +371,7 @@ namespace rsx case window_origin::bottom: return "bottom"; case window_origin::top: return "top"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(window_pixel_center in) @@ -381,7 +381,7 @@ namespace rsx case window_pixel_center::half: return "half"; case window_pixel_center::integer: return "integer"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(user_clip_plane_op op) @@ -392,7 +392,7 @@ namespace rsx case user_clip_plane_op::greater_or_equal: return "greater or equal"; case user_clip_plane_op::less_than: return "less than"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } @@ -404,7 +404,7 @@ namespace rsx case surface_depth_format::z16: return "CELL_GCM_SURFACE_Z16"; case surface_depth_format::z24s8: return "CELL_GCM_SURFACE_Z24S8"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(surface_antialiasing format) @@ -416,7 +416,7 @@ namespace rsx case surface_antialiasing::square_centered_4_samples: return "4 samples square centered"; case surface_antialiasing::square_rotated_4_samples: return "4 samples diagonal rotated"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(surface_color_format format) @@ -438,7 +438,7 @@ namespace rsx case surface_color_format::x8b8g8r8_o8b8g8r8: return "CELL_GCM_SURFACE_X8B8G8R8_O8B8G8R8"; case surface_color_format::a8b8g8r8: return "CELL_GCM_SURFACE_A8B8G8R8"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(index_array_type arg) @@ -448,7 +448,7 @@ namespace rsx case index_array_type::u16: return "unsigned short"; case index_array_type::u32: return "unsigned int"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(blit_engine::context_dma op) @@ -459,7 +459,7 @@ namespace rsx case blit_engine::context_dma::to_memory_get_report: return "to memory get report"; case blit_engine::context_dma::memory_host_buffer: return "memory host buffer"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(blit_engine::transfer_origin op) @@ -469,7 +469,7 @@ namespace rsx case blit_engine::transfer_origin::center: return "center"; case blit_engine::transfer_origin::corner: return "corner"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(blit_engine::transfer_interpolator op) @@ -479,7 +479,7 @@ namespace rsx case blit_engine::transfer_interpolator::foh: return "foh"; case blit_engine::transfer_interpolator::zoh: return "zoh"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(shading_mode op) @@ -489,7 +489,7 @@ namespace rsx case shading_mode::flat: return "flat"; case shading_mode::smooth: return "smooth"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } std::string to_string(polygon_mode op) @@ -500,7 +500,7 @@ namespace rsx case polygon_mode::line: return "line"; case polygon_mode::point: return "point"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } } // end namespace rsx diff --git a/rpcs3/Emu/RSX/rsx_decode.h b/rpcs3/Emu/RSX/rsx_decode.h index f41e605e1f..2e33b0ac4a 100644 --- a/rpcs3/Emu/RSX/rsx_decode.h +++ b/rpcs3/Emu/RSX/rsx_decode.h @@ -1,6 +1,7 @@ #pragma once #include "Utilities/types.h" #include "Utilities/BitField.h" +#include "Utilities/StrFmt.h" #include #include "gcm_enums.h" #pragma warning(disable:4503) @@ -27,7 +28,7 @@ namespace case rsx::vertex_base_type::cmp: return "CMP"; case rsx::vertex_base_type::ub256: return "Unsigned byte unormalized"; } - throw; + fmt::throw_exception("Unexpected enum found" HERE); } }