From 2c34195954a84e99f2fabf7d5351c1d27a897101 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 4 Jul 2018 22:41:34 +0300 Subject: [PATCH] rsx/vp: Discard broken vertex programs with no writes to POS register --- .../RSX/Common/VertexProgramDecompiler.cpp | 9 +++++++- .../D3D12/D3D12VertexProgramDecompiler.cpp | 22 +++++++++++++++---- rpcs3/Emu/RSX/GL/GLVertexProgram.cpp | 10 ++++----- rpcs3/Emu/RSX/VK/VKVertexProgram.cpp | 12 +++++----- 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp index 2737c6a108..47e6657b79 100644 --- a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp @@ -52,7 +52,7 @@ std::string VertexProgramDecompiler::GetDST(bool isSca) default: if (d3.dst > 15) LOG_ERROR(RSX, "dst index out of range: %u", d3.dst); - ret += m_parr.AddParam(PF_PARAM_NONE, getFloatTypeName(4), std::string("dst_reg") + std::to_string(d3.dst), d3.dst == 0 ? getFloatTypeName(4) + "(0.0f, 0.0f, 0.0f, 1.0f)" : getFloatTypeName(4) + "(0.0, 0.0, 0.0, 0.0)") + mask; + ret += m_parr.AddParam(PF_PARAM_OUT, getFloatTypeName(4), std::string("dst_reg") + std::to_string(d3.dst), d3.dst == 0 ? getFloatTypeName(4) + "(0.0f, 0.0f, 0.0f, 1.0f)" : getFloatTypeName(4) + "(0.0, 0.0, 0.0, 0.0)") + mask; // Handle double destination register as 'dst_reg = tmp' if (d0.dst_tmp != 0x3f) ret += " = " + m_parr.AddParam(PF_PARAM_NONE, getFloatTypeName(4), std::string("tmp") + std::to_string(d0.dst_tmp)) + mask; @@ -391,6 +391,13 @@ std::string VertexProgramDecompiler::BuildCode() lvl += m_instructions[i].open_scopes; } + bool is_valid = m_parr.HasParam(PF_PARAM_OUT, getFloatTypeName(4), "dst_reg0"); + if (!is_valid) + { + LOG_WARNING(RSX, "Vertex program has no POS output, shader will be NOPed"); + main_body = "/*" + main_body + "*/"; + } + std::stringstream OS; insertHeader(OS); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp index 5545e1726d..6476501b8c 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp @@ -175,7 +175,7 @@ void D3D12VertexProgramDecompiler::insertMainStart(std::stringstream & OS) OS << "PixelInput main(uint vertex_id : SV_VertexID)\n"; OS << "{\n"; - // Declare inside main function + // Declare temp registers for (const ParamType PT : m_parr.params[PF_PARAM_NONE]) { for (const ParamItem &PI : PT.items) @@ -189,6 +189,20 @@ void D3D12VertexProgramDecompiler::insertMainStart(std::stringstream & OS) } } + // Declare outputs + for (const ParamType PT : m_parr.params[PF_PARAM_OUT]) + { + for (const ParamItem &PI : PT.items) + { + OS << " " << PT.type << " " << PI.name; + if (!PI.value.empty()) + OS << " = " << PI.value; + else + OS << " = " << "float4(0., 0., 0., 0.);"; + OS << ";\n"; + } + } + for (const ParamType PT : m_parr.params[PF_PARAM_IN]) { for (const ParamItem &PI : PT.items) @@ -212,7 +226,7 @@ void D3D12VertexProgramDecompiler::insertMainEnd(std::stringstream & OS) // Declare inside main function for (auto &i : reg_table) { - if (m_parr.HasParam(PF_PARAM_NONE, "float4", i.src_reg)) + if (m_parr.HasParam(PF_PARAM_OUT, "float4", i.src_reg)) { if (i.name == "front_diff_color") insert_front_diffuse = false; @@ -238,11 +252,11 @@ void D3D12VertexProgramDecompiler::insertMainEnd(std::stringstream & OS) //If 2 sided lighting is active and only back is written, copy the value to the front side (Outrun online arcade) if (insert_front_diffuse && insert_back_diffuse) - if (m_parr.HasParam(PF_PARAM_NONE, "float4", "dst_reg1")) + if (m_parr.HasParam(PF_PARAM_OUT, "float4", "dst_reg1")) OS << " Out.dst_reg3 = dst_reg1;\n"; if (insert_front_specular && insert_back_specular) - if (m_parr.HasParam(PF_PARAM_NONE, "float4", "dst_reg2")) + if (m_parr.HasParam(PF_PARAM_OUT, "float4", "dst_reg2")) OS << " Out.dst_reg4 = dst_reg2;\n"; OS << " Out.dst_reg0 = mul(Out.dst_reg0, scaleOffsetMat);\n"; diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp index 9f2459e6bb..239e62366c 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp @@ -156,7 +156,7 @@ void GLVertexDecompilerThread::insertMainStart(std::stringstream & OS) for (int i = 0; i < 16; ++i) { std::string reg_name = "dst_reg" + std::to_string(i); - if (m_parr.HasParam(PF_PARAM_NONE, "vec4", reg_name)) + if (m_parr.HasParam(PF_PARAM_OUT, "vec4", reg_name)) { if (parameters.length()) parameters += ", "; @@ -213,7 +213,7 @@ void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS) std::string parameters = ""; - if (ParamType *vec4Types = m_parr.SearchParam(PF_PARAM_NONE, "vec4")) + if (ParamType *vec4Types = m_parr.SearchParam(PF_PARAM_OUT, "vec4")) { for (int i = 0; i < 16; ++i) { @@ -258,7 +258,7 @@ void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS) if (front_back_specular && name == "spec_color") name = "back_spec_color"; - if (m_parr.HasParam(PF_PARAM_NONE, "vec4", i.src_reg)) + if (m_parr.HasParam(PF_PARAM_OUT, "vec4", i.src_reg)) { if (i.check_mask && (rsx_vertex_program.output_mask & i.check_mask_value) == 0) continue; @@ -290,11 +290,11 @@ void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS) } if (insert_back_diffuse && insert_front_diffuse) - if (m_parr.HasParam(PF_PARAM_NONE, "vec4", "dst_reg1")) + if (m_parr.HasParam(PF_PARAM_OUT, "vec4", "dst_reg1")) OS << " front_diff_color = dst_reg1;\n"; if (insert_back_specular && insert_front_specular) - if (m_parr.HasParam(PF_PARAM_NONE, "vec4", "dst_reg2")) + if (m_parr.HasParam(PF_PARAM_OUT, "vec4", "dst_reg2")) OS << " front_spec_color = dst_reg2;\n"; OS << " gl_PointSize = point_size;\n"; diff --git a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp index a9c7a43812..ed49514dbc 100644 --- a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp @@ -150,7 +150,7 @@ void VKVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std:: for (auto &i : reg_table) { - if (m_parr.HasParam(PF_PARAM_NONE, "vec4", i.src_reg) && i.need_declare) + if (m_parr.HasParam(PF_PARAM_OUT, "vec4", i.src_reg) && i.need_declare) { if (i.check_mask && (rsx_vertex_program.output_mask & i.check_mask_value) == 0) continue; @@ -192,7 +192,7 @@ void VKVertexDecompilerThread::insertMainStart(std::stringstream & OS) for (int i = 0; i < 16; ++i) { std::string reg_name = "dst_reg" + std::to_string(i); - if (m_parr.HasParam(PF_PARAM_NONE, "vec4", reg_name)) + if (m_parr.HasParam(PF_PARAM_OUT, "vec4", reg_name)) { if (parameters.length()) parameters += ", "; @@ -238,7 +238,7 @@ void VKVertexDecompilerThread::insertMainEnd(std::stringstream & OS) std::string parameters = ""; - if (ParamType *vec4Types = m_parr.SearchParam(PF_PARAM_NONE, "vec4")) + if (ParamType *vec4Types = m_parr.SearchParam(PF_PARAM_OUT, "vec4")) { for (int i = 0; i < 16; ++i) { @@ -272,7 +272,7 @@ void VKVertexDecompilerThread::insertMainEnd(std::stringstream & OS) for (auto &i : reg_table) { - if (m_parr.HasParam(PF_PARAM_NONE, "vec4", i.src_reg)) + if (m_parr.HasParam(PF_PARAM_OUT, "vec4", i.src_reg)) { if (i.check_mask && (rsx_vertex_program.output_mask & i.check_mask_value) == 0) continue; @@ -305,11 +305,11 @@ void VKVertexDecompilerThread::insertMainEnd(std::stringstream & OS) } if (insert_back_diffuse && insert_front_diffuse) - if (m_parr.HasParam(PF_PARAM_NONE, "vec4", "dst_reg1")) + if (m_parr.HasParam(PF_PARAM_OUT, "vec4", "dst_reg1")) OS << " front_diff_color = dst_reg1;\n"; if (insert_back_specular && insert_front_specular) - if (m_parr.HasParam(PF_PARAM_NONE, "vec4", "dst_reg2")) + if (m_parr.HasParam(PF_PARAM_OUT, "vec4", "dst_reg2")) OS << " front_spec_color = dst_reg2;\n"; OS << " gl_PointSize = point_size;\n";