diff --git a/rpcs3/Emu/RSX/Common/ShaderParam.h b/rpcs3/Emu/RSX/Common/ShaderParam.h index 5f9702cb12..20d27f0dc7 100644 --- a/rpcs3/Emu/RSX/Common/ShaderParam.h +++ b/rpcs3/Emu/RSX/Common/ShaderParam.h @@ -245,3 +245,17 @@ public: return name + "." + fmt::merge({ swizzles }, "."); } }; + +struct vertex_reg_info +{ + std::string name; //output name + bool need_declare; //needs explicit declaration as output (not language in-built) + std::string src_reg; //reg to get data from + std::string src_reg_mask; //input swizzle mask + bool need_cast; //needs casting + std::string cond; //update on condition + std::string default_val; //fallback value on cond fail + std::string dst_alias; //output name override + bool check_mask; //check program output control mask for this output + u32 check_mask_value; //program output control mask for testing +}; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index f145dee081..ffc3ac9efb 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -89,8 +89,7 @@ void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex) void *mapped_buffer = m_buffer_data.map(CD3DX12_RANGE(heap_offset, heap_offset + 512)); fill_scale_offset_data(mapped_buffer, true, false); fill_user_clip_data((char*)mapped_buffer + 64); - - fill_fragment_state_buffer((char *)mapped_buffer + 96, m_fragment_program); + fill_fragment_state_buffer((char *)mapped_buffer + 128, m_fragment_program); m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + 512)); D3D12_CONSTANT_BUFFER_VIEW_DESC constant_buffer_view_desc = { diff --git a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp index 9a35963792..562a022b8c 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp @@ -38,7 +38,8 @@ void D3D12FragmentDecompiler::insertHeader(std::stringstream & OS) OS << "cbuffer SCALE_OFFSET : register(b0)" << std::endl; OS << "{" << std::endl; OS << " float4x4 scaleOffsetMat;" << std::endl; - OS << " float4 userClip[2];" << std::endl; + OS << " int4 userClipEnabled[2];" << std::endl; + OS << " float4 userClipFactor[2];" << std::endl; OS << " float fog_param0;\n"; OS << " float fog_param1;\n"; OS << " int isAlphaTested;" << std::endl; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp index 0c689b3079..c3f8d1517e 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp @@ -31,7 +31,8 @@ void D3D12VertexProgramDecompiler::insertHeader(std::stringstream &OS) OS << "cbuffer SCALE_OFFSET : register(b0)" << std::endl; OS << "{" << std::endl; OS << " float4x4 scaleOffsetMat;" << std::endl; - OS << " float4 userClip[2];" << std::endl; + OS << " int4 userClipEnabled[2];" << std::endl; + OS << " float4 userClipFactor[2];" << std::endl; OS << " float fog_param0;" << std::endl; OS << " float fog_param1;" << std::endl; OS << " int isAlphaTested;" << std::endl; @@ -110,31 +111,21 @@ void D3D12VertexProgramDecompiler::insertOutputs(std::stringstream & OS, const s OS << "};" << std::endl; } -struct reg_info -{ - std::string name; - bool need_declare; - std::string src_reg; - std::string src_reg_mask; - bool need_cast; -}; - -static const reg_info reg_table[] = +static const vertex_reg_info reg_table[] = { { "gl_Position", false, "dst_reg0", "", false }, { "diff_color", true, "dst_reg1", "", false }, { "spec_color", true, "dst_reg2", "", false }, { "front_diff_color", true, "dst_reg3", "", false }, { "front_spec_color", true, "dst_reg4", "", false }, - { "fogc", true, "dst_reg5", ".x", true }, - { "gl_ClipDistance[0]", false, "dst_reg5", ".y", false }, - { "gl_ClipDistance[1]", false, "dst_reg5", ".z", false }, - { "gl_ClipDistance[2]", false, "dst_reg5", ".w", false }, - // TODO: Handle user clip distance properly -/* { "gl_PointSize", false, "dst_reg6", ".x", false }, - { "gl_ClipDistance[3]", false, "dst_reg6", ".y", false }, - { "gl_ClipDistance[4]", false, "dst_reg6", ".z", false }, - { "gl_ClipDistance[5]", false, "dst_reg6", ".w", false },*/ + { "fogc", true, "dst_reg5", ".xxxx", true }, + { "gl_ClipDistance[0]", false, "dst_reg5", ".y * userClipFactor[0].x", false, "userClipEnabled[0].x > 0", "0.5", "Out.dst_userClip0.x" }, + { "gl_ClipDistance[0]", false, "dst_reg5", ".z * userClipFactor[0].y", false, "userClipEnabled[0].y > 0", "0.5", "Out.dst_userClip0.y" }, + { "gl_ClipDistance[0]", false, "dst_reg5", ".w * userClipFactor[0].z", false, "userClipEnabled[0].z > 0", "0.5", "Out.dst_userClip0.z" }, + //{ "gl_PointSize", false, "dst_reg6", ".x", false }, + { "gl_ClipDistance[0]", false, "dst_reg6", ".y * userClipFactor[0].w", false, "userClipEnabled[0].w > 0", "0.5", "Out.dst_userClip0.w" }, + { "gl_ClipDistance[0]", false, "dst_reg6", ".z * userClipFactor[1].x", false, "userClipEnabled[1].x > 0", "0.5", "Out.dst_userClip1.x" }, + { "gl_ClipDistance[0]", false, "dst_reg6", ".w * userClipFactor[1].y", false, "userClipEnabled[1].y > 0", "0.5", "Out.dst_userClip1.y" }, { "tc9", false, "dst_reg6", "", false }, { "tc0", true, "dst_reg7", "", false }, { "tc1", true, "dst_reg8", "", false }, @@ -229,7 +220,19 @@ void D3D12VertexProgramDecompiler::insertMainEnd(std::stringstream & OS) if (i.name == "front_spec_color") insert_front_specular = false; - OS << " Out." << i.src_reg << " = " << i.src_reg << ";" << std::endl; + std::string condition = (!i.cond.empty()) ? "(" + i.cond + ") " : ""; + std::string output_name = i.dst_alias.empty() ? "Out." + i.src_reg : i.dst_alias; + + if (condition.empty() || i.default_val.empty()) + { + if (!condition.empty()) condition = "if " + condition; + OS << " " << condition << output_name << " = " << i.src_reg << i.src_reg_mask << ";" << std::endl; + } + else + { + //Condition and fallback values provided + OS << " " << output_name << " = " << condition << "? " << i.src_reg << i.src_reg_mask << ": " << i.default_val << ";" << std::endl; + } } } @@ -242,20 +245,6 @@ void D3D12VertexProgramDecompiler::insertMainEnd(std::stringstream & OS) if (m_parr.HasParam(PF_PARAM_NONE, "float4", "dst_reg2")) OS << " Out.dst_reg4 = dst_reg2;\n"; - // user clip - if ((rsx_vertex_program.output_mask & (CELL_GCM_ATTRIB_OUTPUT_MASK_UC0 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC1 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC2)) != 0) - { - OS << " Out.dst_userClip0.x = dst_reg5.y * userClip[0].x;\n"; - OS << " Out.dst_userClip0.y = dst_reg5.z * userClip[0].y;\n"; - OS << " Out.dst_userClip0.z = dst_reg5.w * userClip[0].z;\n"; - } - if ((rsx_vertex_program.output_mask & (CELL_GCM_ATTRIB_OUTPUT_MASK_UC3 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC4 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC5)) != 0) - { - OS << " Out.dst_userClip0.w = dst_reg6.y * userClip[0].w;\n"; - OS << " Out.dst_userClip1.x = dst_reg6.z * userClip[1].x;\n"; - OS << " Out.dst_userClip1.y = dst_reg6.w * userClip[1].y;\n"; - } - OS << " Out.dst_reg0 = mul(Out.dst_reg0, scaleOffsetMat);" << std::endl; OS << " return Out;" << std::endl; OS << "}" << std::endl; diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 19eeca992f..6eddff39a4 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -289,13 +289,6 @@ void GLGSRender::begin() //NV4097_SET_ANTI_ALIASING_CONTROL //NV4097_SET_CLIP_ID_TEST_ENABLE - __glcheck enable(true, GL_CLIP_DISTANCE0 + 0); - __glcheck enable(true, GL_CLIP_DISTANCE0 + 1); - __glcheck enable(true, GL_CLIP_DISTANCE0 + 2); - __glcheck enable(true, GL_CLIP_DISTANCE0 + 3); - __glcheck enable(true, GL_CLIP_DISTANCE0 + 4); - __glcheck enable(true, GL_CLIP_DISTANCE0 + 5); - std::chrono::time_point now = steady_clock::now(); m_begin_time += (u32)std::chrono::duration_cast(now - then).count(); } @@ -573,6 +566,14 @@ void GLGSRender::on_init_thread() m_gl_sampler_states[i].bind(i); } + //Clip planes are shader controlled; enable all planes driver-side + glEnable(GL_CLIP_DISTANCE0 + 0); + glEnable(GL_CLIP_DISTANCE0 + 1); + glEnable(GL_CLIP_DISTANCE0 + 2); + glEnable(GL_CLIP_DISTANCE0 + 3); + glEnable(GL_CLIP_DISTANCE0 + 4); + glEnable(GL_CLIP_DISTANCE0 + 5); + m_gl_texture_cache.initialize(this); } diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp index 36cbccfc19..598929466d 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp @@ -34,7 +34,8 @@ void GLVertexDecompilerThread::insertHeader(std::stringstream &OS) OS << "layout(std140, binding = 0) uniform ScaleOffsetBuffer" << std::endl; OS << "{" << std::endl; OS << " mat4 scaleOffsetMat;" << std::endl; - OS << " vec4 userClip[2];" << std::endl; + OS << " ivec4 userClipEnabled[2];" << std::endl; + OS << " vec4 userClipFactor[2];" << std::endl; OS << "};" << std::endl; } @@ -81,11 +82,6 @@ void GLVertexDecompilerThread::insertInputs(std::stringstream & OS, const std::v } } } - - for (int i = 0; i <= 5; i++) - { - OS << "uniform int uc_m" + std::to_string(i) + "= 0;\n"; - } } void GLVertexDecompilerThread::insertConstants(std::stringstream & OS, const std::vector & constants) @@ -108,30 +104,22 @@ void GLVertexDecompilerThread::insertConstants(std::stringstream & OS, const std } } -struct reg_info -{ - std::string name; - bool need_declare; - std::string src_reg; - std::string src_reg_mask; - bool need_cast; -}; - -static const reg_info reg_table[] = +static const vertex_reg_info reg_table[] = { { "gl_Position", false, "dst_reg0", "", false }, { "diff_color", true, "dst_reg1", "", false }, { "spec_color", true, "dst_reg2", "", false }, { "front_diff_color", true, "dst_reg3", "", false }, { "front_spec_color", true, "dst_reg4", "", false }, - { "fog_c", true, "dst_reg5", ".xxxx", true }, - { "gl_ClipDistance[0]", false, "dst_reg5", ".y * userClip[0].x", false }, - { "gl_ClipDistance[1]", false, "dst_reg5", ".z * userClip[0].y", false }, - { "gl_ClipDistance[2]", false, "dst_reg5", ".w * userClip[0].z", false }, + { "fog_c", true, "dst_reg5", ".xxxx", true, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_FOG }, + //Warning: Always define all 3 clip plane groups together to avoid flickering with openGL + { "gl_ClipDistance[0]", false, "dst_reg5", ".y * userClipFactor[0].x", false, "userClipEnabled[0].x > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC0 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC1 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC2 }, + { "gl_ClipDistance[1]", false, "dst_reg5", ".z * userClipFactor[0].y", false, "userClipEnabled[0].y > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC0 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC1 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC2 }, + { "gl_ClipDistance[2]", false, "dst_reg5", ".w * userClipFactor[0].z", false, "userClipEnabled[0].z > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC0 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC1 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC2 }, { "gl_PointSize", false, "dst_reg6", ".x", false }, - { "gl_ClipDistance[3]", false, "dst_reg6", ".y * userClip[0].w", false }, - { "gl_ClipDistance[4]", false, "dst_reg6", ".z * userClip[1].x", false }, - { "gl_ClipDistance[5]", false, "dst_reg6", ".w * userClip[1].y", false }, + { "gl_ClipDistance[3]", false, "dst_reg6", ".y * userClipFactor[0].w", false, "userClipEnabled[0].w > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC3 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC4 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC5 }, + { "gl_ClipDistance[4]", false, "dst_reg6", ".z * userClipFactor[1].x", false, "userClipEnabled[1].x > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC3 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC4 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC5 }, + { "gl_ClipDistance[5]", false, "dst_reg6", ".w * userClipFactor[1].y", false, "userClipEnabled[1].y > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC3 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC4 | CELL_GCM_ATTRIB_OUTPUT_MASK_UC5 }, { "tc0", true, "dst_reg7", "", false }, { "tc1", true, "dst_reg8", "", false }, { "tc2", true, "dst_reg9", "", false }, @@ -141,7 +129,7 @@ static const reg_info reg_table[] = { "tc6", true, "dst_reg13", "", false }, { "tc7", true, "dst_reg14", "", false }, { "tc8", true, "dst_reg15", "", false }, - { "tc9", true, "dst_reg6", "", false } // In this line, dst_reg6 is correct since dst_reg goes from 0 to 15. + { "tc9", true, "dst_reg6", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX9 } // In this line, dst_reg6 is correct since dst_reg goes from 0 to 15. }; void GLVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std::vector & outputs) @@ -159,6 +147,9 @@ void GLVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std:: { if (m_parr.HasParam(PF_PARAM_NONE, "vec4", i.src_reg) && i.need_declare) { + if (i.check_mask && (rsx_vertex_program.output_mask & i.check_mask_value) == 0) + continue; + if (i.name == "front_diff_color") insert_front_diffuse = false; @@ -333,6 +324,9 @@ void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS) { if (m_parr.HasParam(PF_PARAM_NONE, "vec4", i.src_reg)) { + if (i.check_mask && (rsx_vertex_program.output_mask & i.check_mask_value) == 0) + continue; + if (i.name == "front_diff_color") insert_front_diffuse = false; @@ -340,6 +334,7 @@ void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS) insert_front_specular = false; std::string name = i.name; + std::string condition = (!i.cond.empty()) ? "(" + i.cond + ") " : ""; if (front_back_diffuse && name == "diff_color") name = "back_diff_color"; @@ -347,7 +342,16 @@ void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS) if (front_back_specular && name == "spec_color") name = "back_spec_color"; - OS << " " << name << " = " << i.src_reg << i.src_reg_mask << ";" << std::endl; + if (condition.empty() || i.default_val.empty()) + { + if (!condition.empty()) condition = "if " + condition; + OS << " " << condition << name << " = " << i.src_reg << i.src_reg_mask << ";" << std::endl; + } + else + { + //Insert if-else condition + OS << " " << name << " = " << condition << "? " << i.src_reg << i.src_reg_mask << ": " << i.default_val << ";" << std::endl; + } } } diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 709431235f..bf66135ddd 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -601,32 +601,35 @@ namespace rsx rsx::method_registers.clip_plane_5_enabled(), }; - std::array tmp{}; + s32 clip_enabled_flags[8] = {}; + f32 clip_distance_factors[8] = {}; + for (int index = 0; index < 6; ++index) { - f32 value = 0; switch (clip_plane_control[index]) { default: LOG_ERROR(RSX, "bad clip plane control (0x%x)", (u8)clip_plane_control[index]); case rsx::user_clip_plane_op::disable: - value = 0.f; + clip_enabled_flags[index] = 0; + clip_distance_factors[index] = 0.f; break; case rsx::user_clip_plane_op::greater_or_equal: - value = 1.f; + clip_enabled_flags[index] = 1; + clip_distance_factors[index] = 1.f; break; case rsx::user_clip_plane_op::less_than: - value = -1.f; + clip_enabled_flags[index] = 1; + clip_distance_factors[index] = -1.f; break; } - - tmp[index] = value; } - stream_vector_from_memory((char*)buffer, tmp.data()); - stream_vector_from_memory((char*)buffer + 16, &tmp[4]); + + memcpy(buffer, clip_enabled_flags, 32); + memcpy((char*)buffer + 32, clip_distance_factors, 32); } /** diff --git a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp index cb7ea8fdde..8526bd1886 100644 --- a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp @@ -33,7 +33,8 @@ void VKVertexDecompilerThread::insertHeader(std::stringstream &OS) OS << "layout(std140, set = 0, binding = 0) uniform ScaleOffsetBuffer" << std::endl; OS << "{" << std::endl; OS << " mat4 scaleOffsetMat;" << std::endl; - OS << " vec4 userClip[2];" << std::endl; + OS << " ivec4 userClipEnabled[2];" << std::endl; + OS << " vec4 userClipFactor[2];" << std::endl; OS << "};" << std::endl; vk::glsl::program_input in; @@ -142,34 +143,22 @@ void VKVertexDecompilerThread::insertConstants(std::stringstream & OS, const std } } -struct reg_info -{ - std::string name; - bool need_declare; - std::string src_reg; - std::string src_reg_mask; - bool need_cast; -}; - -static const reg_info reg_table[] = +static const vertex_reg_info reg_table[] = { { "gl_Position", false, "dst_reg0", "", false }, { "back_diff_color", true, "dst_reg1", "", false }, { "back_spec_color", true, "dst_reg2", "", false }, { "front_diff_color", true, "dst_reg3", "", false }, { "front_spec_color", true, "dst_reg4", "", false }, - { "fog_c", true, "dst_reg5", ".xxxx", true }, - { "gl_ClipDistance[0]", false, "dst_reg5", ".y * userClip[0].x", false }, - { "gl_ClipDistance[1]", false, "dst_reg5", ".z * userClip[0].y", false }, - { "gl_ClipDistance[2]", false, "dst_reg5", ".w * userClip[0].z", false }, + { "fog_c", true, "dst_reg5", ".xxxx", true, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_FOG }, + //Warning: With spir-v if you declare clip distance var, you must assign a value even when its disabled! Runtime does not assign a default value + { "gl_ClipDistance[0]", false, "dst_reg5", ".y * userClipFactor[0].x", false, "userClipEnabled[0].x > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC0 }, + { "gl_ClipDistance[1]", false, "dst_reg5", ".z * userClipFactor[0].y", false, "userClipEnabled[0].y > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC1 }, + { "gl_ClipDistance[2]", false, "dst_reg5", ".w * userClipFactor[0].z", false, "userClipEnabled[0].z > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC2 }, { "gl_PointSize", false, "dst_reg6", ".x", false }, - - //Disable user clip planes until they are properly handled - - { "gl_ClipDistance[3]", false, "dst_reg6", ".y * userClip[0].w", false }, - { "gl_ClipDistance[4]", false, "dst_reg6", ".z * userClip[1].x", false }, - { "gl_ClipDistance[5]", false, "dst_reg6", ".w * userClip[1].y", false }, - + { "gl_ClipDistance[3]", false, "dst_reg6", ".y * userClipFactor[0].w", false, "userClipEnabled[0].w > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC3 }, + { "gl_ClipDistance[4]", false, "dst_reg6", ".z * userClipFactor[1].x", false, "userClipEnabled[1].x > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC4 }, + { "gl_ClipDistance[5]", false, "dst_reg6", ".w * userClipFactor[1].y", false, "userClipEnabled[1].y > 0", "0.5", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_UC5 }, { "tc0", true, "dst_reg7", "", false }, { "tc1", true, "dst_reg8", "", false }, { "tc2", true, "dst_reg9", "", false }, @@ -179,7 +168,7 @@ static const reg_info reg_table[] = { "tc6", true, "dst_reg13", "", false }, { "tc7", true, "dst_reg14", "", false }, { "tc8", true, "dst_reg15", "", false }, - { "tc9", true, "dst_reg6", "", false } // In this line, dst_reg6 is correct since dst_reg goes from 0 to 15. + { "tc9", true, "dst_reg6", "", false, "", "", "", true, CELL_GCM_ATTRIB_OUTPUT_MASK_TEX9 } // In this line, dst_reg6 is correct since dst_reg goes from 0 to 15. }; void VKVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std::vector & outputs) @@ -194,6 +183,9 @@ void VKVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std:: { if (m_parr.HasParam(PF_PARAM_NONE, "vec4", i.src_reg) && i.need_declare) { + if (i.check_mask && (rsx_vertex_program.output_mask & i.check_mask_value) == 0) + continue; + if (i.name == "front_diff_color") insert_front_diffuse = false; @@ -335,13 +327,27 @@ void VKVertexDecompilerThread::insertMainEnd(std::stringstream & OS) { if (m_parr.HasParam(PF_PARAM_NONE, "vec4", i.src_reg)) { + if (i.check_mask && (rsx_vertex_program.output_mask & i.check_mask_value) == 0) + continue; + if (i.name == "front_diff_color") insert_front_diffuse = false; if (i.name == "front_spec_color") insert_front_specular = false; - OS << " " << i.name << " = " << i.src_reg << i.src_reg_mask << ";" << std::endl; + std::string condition = (!i.cond.empty()) ? "(" + i.cond + ") " : ""; + + if (condition.empty() || i.default_val.empty()) + { + if (!condition.empty()) condition = "if " + condition; + OS << " " << condition << i.name << " = " << i.src_reg << i.src_reg_mask << ";" << std::endl; + } + else + { + //Insert if-else condition + OS << " " << i.name << " = " << condition << "? " << i.src_reg << i.src_reg_mask << ": " << i.default_val << ";" << std::endl; + } } }