mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 17:11:23 +00:00
rsx: Minor bug fixes
- vk: Do not select first available format when choosing a swapchain format - gl/vk: Ignore rendering zero sized framebuffers/scissors - fp: Re-enable range clamp on fp16 registers; fix fx12 clamping [-2, 2]
This commit is contained in:
parent
d43e06c0ea
commit
9e7a42d057
@ -37,13 +37,12 @@ void FragmentProgramDecompiler::SetDst(std::string code, bool append_mask)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dst.saturate)
|
if (!dst.no_dest)
|
||||||
{
|
|
||||||
code = saturate(code);
|
|
||||||
}
|
|
||||||
else if (!dst.no_dest)
|
|
||||||
{
|
{
|
||||||
code = NoOverflow(code);
|
code = NoOverflow(code);
|
||||||
|
|
||||||
|
if (dst.saturate)
|
||||||
|
code = saturate(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
code += (append_mask ? "$m" : "");
|
code += (append_mask ? "$m" : "");
|
||||||
@ -64,13 +63,6 @@ void FragmentProgramDecompiler::SetDst(std::string code, bool append_mask)
|
|||||||
|
|
||||||
std::string dest = AddReg(dst.dest_reg, dst.fp16) + "$m";
|
std::string dest = AddReg(dst.dest_reg, dst.fp16) + "$m";
|
||||||
|
|
||||||
if (dst.exp_tex)
|
|
||||||
{
|
|
||||||
//TODO
|
|
||||||
//If exp_tex really sets _bx2 flag, we may need to perform extra modifications to the src
|
|
||||||
AddCode("//TODO: exp tex flag is set");
|
|
||||||
}
|
|
||||||
|
|
||||||
AddCodeCond(Format(dest), code);
|
AddCodeCond(Format(dest), code);
|
||||||
//AddCode("$ifcond " + dest + code + (append_mask ? "$m;" : ";"));
|
//AddCode("$ifcond " + dest + code + (append_mask ? "$m;" : ";"));
|
||||||
|
|
||||||
@ -206,6 +198,7 @@ std::string FragmentProgramDecompiler::NoOverflow(const std::string& code)
|
|||||||
if (dst.exp_tex)
|
if (dst.exp_tex)
|
||||||
{
|
{
|
||||||
//If dst.exp_tex really is _bx2 postfix, we need to unpack dynamic range
|
//If dst.exp_tex really is _bx2 postfix, we need to unpack dynamic range
|
||||||
|
AddCode("//exp tex flag is set");
|
||||||
return "((" + code + "- 0.5) * 2.)";
|
return "((" + code + "- 0.5) * 2.)";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,11 +207,9 @@ std::string FragmentProgramDecompiler::NoOverflow(const std::string& code)
|
|||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
//Disabled: Causes blue output in some games such as persona V and soul calibur IV
|
return "clamp(" + code + ", -65504., 65504.)";
|
||||||
//return "clamp(" + code + ", -65504., 65504.)";
|
|
||||||
break;
|
|
||||||
case 2:
|
case 2:
|
||||||
return "clamp(" + code + ", -1., 1.)";
|
return "clamp(" + code + ", -2., 2.)";
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
@ -191,7 +191,7 @@ void GLGSRender::begin()
|
|||||||
|
|
||||||
init_buffers();
|
init_buffers();
|
||||||
|
|
||||||
if (!draw_fbo.check())
|
if (!framebuffer_status_valid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::chrono::time_point<steady_clock> then = steady_clock::now();
|
std::chrono::time_point<steady_clock> then = steady_clock::now();
|
||||||
@ -322,7 +322,7 @@ namespace
|
|||||||
|
|
||||||
void GLGSRender::end()
|
void GLGSRender::end()
|
||||||
{
|
{
|
||||||
if (skip_frame || !draw_fbo || !draw_fbo.check())
|
if (skip_frame || !framebuffer_status_valid)
|
||||||
{
|
{
|
||||||
rsx::thread::end();
|
rsx::thread::end();
|
||||||
return;
|
return;
|
||||||
@ -523,13 +523,26 @@ void GLGSRender::end()
|
|||||||
void GLGSRender::set_viewport()
|
void GLGSRender::set_viewport()
|
||||||
{
|
{
|
||||||
//NOTE: scale offset matrix already contains the viewport transformation
|
//NOTE: scale offset matrix already contains the viewport transformation
|
||||||
glViewport(0, 0, rsx::method_registers.surface_clip_width(), rsx::method_registers.surface_clip_height());
|
const auto clip_width = rsx::method_registers.surface_clip_width();
|
||||||
|
const auto clip_height = rsx::method_registers.surface_clip_height();
|
||||||
|
glViewport(0, 0, clip_width, clip_height);
|
||||||
|
|
||||||
u16 scissor_x = rsx::method_registers.scissor_origin_x();
|
u16 scissor_x = rsx::method_registers.scissor_origin_x();
|
||||||
u16 scissor_w = rsx::method_registers.scissor_width();
|
u16 scissor_w = rsx::method_registers.scissor_width();
|
||||||
u16 scissor_y = rsx::method_registers.scissor_origin_y();
|
u16 scissor_y = rsx::method_registers.scissor_origin_y();
|
||||||
u16 scissor_h = rsx::method_registers.scissor_height();
|
u16 scissor_h = rsx::method_registers.scissor_height();
|
||||||
|
|
||||||
|
//Do not bother drawing anything if output is zero sized
|
||||||
|
//TODO: Clip scissor region
|
||||||
|
if (scissor_x >= clip_width || scissor_y >= clip_height || scissor_w == 0 || scissor_h == 0)
|
||||||
|
{
|
||||||
|
if (!g_cfg.video.strict_rendering_mode)
|
||||||
|
{
|
||||||
|
framebuffer_status_valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//NOTE: window origin does not affect scissor region (probably only affects viewport matrix; already applied)
|
//NOTE: window origin does not affect scissor region (probably only affects viewport matrix; already applied)
|
||||||
//See LIMBO [NPUB-30373] which uses shader window origin = top
|
//See LIMBO [NPUB-30373] which uses shader window origin = top
|
||||||
__glcheck glScissor(scissor_x, scissor_y, scissor_w, scissor_h);
|
__glcheck glScissor(scissor_x, scissor_y, scissor_w, scissor_h);
|
||||||
@ -726,7 +739,7 @@ void GLGSRender::on_exit()
|
|||||||
|
|
||||||
void GLGSRender::clear_surface(u32 arg)
|
void GLGSRender::clear_surface(u32 arg)
|
||||||
{
|
{
|
||||||
if (skip_frame) return;
|
if (skip_frame || !framebuffer_status_valid) return;
|
||||||
if (rsx::method_registers.surface_color_target() == rsx::surface_target::none) return;
|
if (rsx::method_registers.surface_color_target() == rsx::surface_target::none) return;
|
||||||
if ((arg & 0xf3) == 0) return;
|
if ((arg & 0xf3) == 0) return;
|
||||||
|
|
||||||
|
@ -70,6 +70,8 @@ private:
|
|||||||
std::mutex queue_guard;
|
std::mutex queue_guard;
|
||||||
std::list<work_item> work_queue;
|
std::list<work_item> work_queue;
|
||||||
|
|
||||||
|
bool framebuffer_status_valid = false;
|
||||||
|
|
||||||
rsx::gcm_framebuffer_info surface_info[rsx::limits::color_buffers_count];
|
rsx::gcm_framebuffer_info surface_info[rsx::limits::color_buffers_count];
|
||||||
rsx::gcm_framebuffer_info depth_surface_info;
|
rsx::gcm_framebuffer_info depth_surface_info;
|
||||||
|
|
||||||
|
@ -165,6 +165,12 @@ void GLGSRender::init_buffers(bool skip_reading)
|
|||||||
const u16 clip_horizontal = rsx::method_registers.surface_clip_width();
|
const u16 clip_horizontal = rsx::method_registers.surface_clip_width();
|
||||||
const u16 clip_vertical = rsx::method_registers.surface_clip_height();
|
const u16 clip_vertical = rsx::method_registers.surface_clip_height();
|
||||||
|
|
||||||
|
if (clip_horizontal == 0 || clip_vertical == 0)
|
||||||
|
{
|
||||||
|
LOG_ERROR(RSX, "Invalid framebuffer setup, w=%d, h=%d", clip_horizontal, clip_vertical);
|
||||||
|
framebuffer_status_valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
const auto pitchs = get_pitchs();
|
const auto pitchs = get_pitchs();
|
||||||
const auto surface_format = rsx::method_registers.surface_color();
|
const auto surface_format = rsx::method_registers.surface_color();
|
||||||
const auto depth_format = rsx::method_registers.surface_depth_fmt();
|
const auto depth_format = rsx::method_registers.surface_depth_fmt();
|
||||||
@ -235,8 +241,8 @@ void GLGSRender::init_buffers(bool skip_reading)
|
|||||||
else
|
else
|
||||||
depth_surface_info = {};
|
depth_surface_info = {};
|
||||||
|
|
||||||
if (!draw_fbo.check())
|
framebuffer_status_valid = draw_fbo.check();
|
||||||
return;
|
if (!framebuffer_status_valid) return;
|
||||||
|
|
||||||
draw_fbo.bind();
|
draw_fbo.bind();
|
||||||
set_viewport();
|
set_viewport();
|
||||||
|
@ -838,6 +838,9 @@ void VKGSRender::begin()
|
|||||||
|
|
||||||
init_buffers();
|
init_buffers();
|
||||||
|
|
||||||
|
if (!framebuffer_status_valid)
|
||||||
|
return;
|
||||||
|
|
||||||
float actual_line_width = rsx::method_registers.line_width();
|
float actual_line_width = rsx::method_registers.line_width();
|
||||||
|
|
||||||
vkCmdSetLineWidth(*m_current_command_buffer, actual_line_width);
|
vkCmdSetLineWidth(*m_current_command_buffer, actual_line_width);
|
||||||
@ -898,7 +901,7 @@ void VKGSRender::close_render_pass()
|
|||||||
|
|
||||||
void VKGSRender::end()
|
void VKGSRender::end()
|
||||||
{
|
{
|
||||||
if (skip_frame)
|
if (skip_frame || !framebuffer_status_valid)
|
||||||
{
|
{
|
||||||
rsx::thread::end();
|
rsx::thread::end();
|
||||||
return;
|
return;
|
||||||
@ -1200,6 +1203,15 @@ void VKGSRender::set_viewport()
|
|||||||
scissor.offset.y = scissor_y;
|
scissor.offset.y = scissor_y;
|
||||||
|
|
||||||
vkCmdSetScissor(*m_current_command_buffer, 0, 1, &scissor);
|
vkCmdSetScissor(*m_current_command_buffer, 0, 1, &scissor);
|
||||||
|
|
||||||
|
if (scissor_x >= viewport.width || scissor_y >= viewport.height || scissor_w == 0 || scissor_h == 0)
|
||||||
|
{
|
||||||
|
if (!g_cfg.video.strict_rendering_mode)
|
||||||
|
{
|
||||||
|
framebuffer_status_valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKGSRender::on_init_thread()
|
void VKGSRender::on_init_thread()
|
||||||
@ -1229,6 +1241,9 @@ void VKGSRender::clear_surface(u32 mask)
|
|||||||
if (m_current_present_image == 0xFFFF) return;
|
if (m_current_present_image == 0xFFFF) return;
|
||||||
|
|
||||||
init_buffers();
|
init_buffers();
|
||||||
|
|
||||||
|
if (!framebuffer_status_valid) return;
|
||||||
|
|
||||||
copy_render_targets_to_dma_location();
|
copy_render_targets_to_dma_location();
|
||||||
|
|
||||||
float depth_clear = 1.f;
|
float depth_clear = 1.f;
|
||||||
@ -1834,6 +1849,14 @@ void VKGSRender::prepare_rtts()
|
|||||||
u32 clip_x = rsx::method_registers.surface_clip_origin_x();
|
u32 clip_x = rsx::method_registers.surface_clip_origin_x();
|
||||||
u32 clip_y = rsx::method_registers.surface_clip_origin_y();
|
u32 clip_y = rsx::method_registers.surface_clip_origin_y();
|
||||||
|
|
||||||
|
if (clip_width == 0 || clip_height == 0)
|
||||||
|
{
|
||||||
|
LOG_ERROR(RSX, "Invalid framebuffer setup, w=%d, h=%d", clip_width, clip_height);
|
||||||
|
framebuffer_status_valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
framebuffer_status_valid = true;
|
||||||
|
|
||||||
auto surface_addresses = get_color_surface_addresses();
|
auto surface_addresses = get_color_surface_addresses();
|
||||||
auto zeta_address = get_zeta_surface_address();
|
auto zeta_address = get_zeta_surface_address();
|
||||||
|
|
||||||
|
@ -167,6 +167,8 @@ private:
|
|||||||
u32 m_used_descriptors = 0;
|
u32 m_used_descriptors = 0;
|
||||||
u8 m_draw_buffers_count = 0;
|
u8 m_draw_buffers_count = 0;
|
||||||
|
|
||||||
|
bool framebuffer_status_valid = false;
|
||||||
|
|
||||||
rsx::gcm_framebuffer_info m_surface_info[rsx::limits::color_buffers_count];
|
rsx::gcm_framebuffer_info m_surface_info[rsx::limits::color_buffers_count];
|
||||||
rsx::gcm_framebuffer_info m_depth_surface_info;
|
rsx::gcm_framebuffer_info m_depth_surface_info;
|
||||||
|
|
||||||
|
@ -1293,6 +1293,16 @@ namespace vk
|
|||||||
{
|
{
|
||||||
if (!formatCount) fmt::throw_exception("Format count is zero!" HERE);
|
if (!formatCount) fmt::throw_exception("Format count is zero!" HERE);
|
||||||
format = surfFormats[0].format;
|
format = surfFormats[0].format;
|
||||||
|
|
||||||
|
//Prefer BGRA8_UNORM to avoid sRGB compression (RADV)
|
||||||
|
for (auto& surface_format: surfFormats)
|
||||||
|
{
|
||||||
|
if (surface_format.format == VK_FORMAT_B8G8R8A8_UNORM)
|
||||||
|
{
|
||||||
|
format = VK_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
color_space = surfFormats[0].colorSpace;
|
color_space = surfFormats[0].colorSpace;
|
||||||
|
Loading…
Reference in New Issue
Block a user