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:
kd-11 2017-07-05 01:16:59 +03:00
parent d43e06c0ea
commit 9e7a42d057
7 changed files with 70 additions and 23 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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();

View File

@ -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;

View File

@ -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;