From b72f6da853482d7756f19718fa13be0f25b4e984 Mon Sep 17 00:00:00 2001 From: Oil Date: Sat, 24 Sep 2016 13:21:41 +0300 Subject: [PATCH] Porting of DH's user clip implementation in gl (#2139) * Porting of DH's user clip implementation in gl * Tweak clang-format * rsx: Move inline array to draw_clause structure. * rsx: Use variant based draw commands. * rsx: Dump DRAW_ARRAYS and DRAW_INDEX_ARRAYS. * GL: old recompiler clean up (#2142) * RSX texture refactor (#2144) * gl/vk: Enable vertex texture fetch (#2127) * gl: Enable vertex textures * rsx: use textureLod instead of generic texture sample * rsx: handle uploading of W32_X32_Y32_Z32 * gl: Re-enable proper shader logging remove old logging method that overwrites single file * gl: Declare texture_coord_scale for vertex samplers * gl: texture remap fixes; enable remap for vertex textures * gl: offset texture indices to base layer 16 * rsx: Fix W32_Z32_Y32_X32_FLOAT subresource layout * vk: Enable vertex textures * rsx: define special calls for vertex texture fetch * gl: improved vertex texture fetch setup * vk: Fix texture formats and component mapping * vk: Implement vertex texture fetch functions properly * vk/gl: proper fix for primitive restart index revert inadvertent decompiler update * gl: Disable filtering for vertex textures * Hopefully fix appveyor build (#2148) * GL/Vulkan: Bug fixes and improvements; alphakill for vulkan (#2146) * vk: Zero-initialize some more structs * gl: Clean up fragment program generation code * vk: Enable alpha kill * vk: Fix surface clear; redirect output for surface_type:b * vk: Tie renderpass to program object to avoid incompatible passes * vk: Properly compute descriptor pool size (#2150) * rsx: Set default attribute format to float. * rsx: vertex attribute size is 1 again for CMP, let backend handles this formats properties. * rsx: Move printing function in a separate header/cpp * Porting of DH's user clip implementation in gl --- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 39 ++++++++++++++ rpcs3/Emu/RSX/GL/GLVertexProgram.cpp | 77 +++++++++++++++++++++++++--- 2 files changed, 108 insertions(+), 8 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 91303a2503..420fa3bed9 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -286,6 +286,45 @@ void GLGSRender::begin() //NV4097_SET_FLAT_SHADE_OP //NV4097_SET_EDGE_FLAG + auto set_clip_plane_control = [&](int index, rsx::user_clip_plane_op control) + { + int value = 0; + int location; + + if (m_program->uniforms.has_location("uc_m" + std::to_string(index), &location)) + { + switch (control) + { + default: + LOG_ERROR(RSX, "bad clip plane control (0x%x)", (u8)control); + + case rsx::user_clip_plane_op::disable: + value = 0; + break; + + case rsx::user_clip_plane_op::greather_or_equal: + value = 1; + break; + + case rsx::user_clip_plane_op::less_than: + value = -1; + break; + } + + __glcheck m_program->uniforms[location] = value; + } + + __glcheck enable(value, GL_CLIP_DISTANCE0 + index); + }; + + load_program(); + set_clip_plane_control(0, rsx::method_registers.clip_plane_0_enabled()); + set_clip_plane_control(1, rsx::method_registers.clip_plane_1_enabled()); + set_clip_plane_control(2, rsx::method_registers.clip_plane_2_enabled()); + set_clip_plane_control(3, rsx::method_registers.clip_plane_3_enabled()); + set_clip_plane_control(4, rsx::method_registers.clip_plane_4_enabled()); + set_clip_plane_control(5, rsx::method_registers.clip_plane_5_enabled()); + if (__glcheck enable(rsx::method_registers.cull_face_enabled(), GL_CULL_FACE)) { __glcheck glCullFace(cull_face(rsx::method_registers.cull_face_mode())); diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp index b0072af52b..03777afe56 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp @@ -3,6 +3,7 @@ #include "GLVertexProgram.h" #include "GLCommonDecompiler.h" +#include "../GCM.h" #include @@ -40,6 +41,55 @@ void GLVertexDecompilerThread::insertHeader(std::stringstream &OS) OS << "};" << std::endl; } +std::vector> get_user_clip_planes(const RSXVertexProgram& prog) +{ + std::vector> uc_planes; + + if (prog.output_mask & (1 << 5)) + { + if (prog.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_UC0) + { + uc_planes.push_back({ "uniform int uc_m0 = 0;\n", + "\tgl_ClipDistance[0] = uc_m0 * dst_reg5.y;\n" }); + } + + if (prog.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_UC1) + { + uc_planes.push_back({ "uniform int uc_m1 = 0;\n", + "\tgl_ClipDistance[1] = uc_m1 * dst_reg5.z;\n" }); + } + + if (prog.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_UC2) + { + uc_planes.push_back({ "uniform int uc_m2 = 0;\n", + "\tgl_ClipDistance[2] = uc_m2 * dst_reg5.w;\n" }); + } + } + + if (prog.output_mask & (1 << 6)) + { + if (prog.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_UC3) + { + uc_planes.push_back({ "uniform int uc_m3 = 0;\n", + "\tgl_ClipDistance[3] = uc_m3 * dst_reg6.y;\n" }); + } + + if (prog.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_UC4) + { + uc_planes.push_back({ "uniform int uc_m4 = 0;\n", + "\tgl_ClipDistance[4] = uc_m4 * dst_reg6.z;\n" }); + } + + if (prog.output_mask & CELL_GCM_ATTRIB_OUTPUT_MASK_UC5) + { + uc_planes.push_back({ "uniform int uc_m5 = 0;\n", + "\tgl_ClipDistance[5] = uc_m5 * dst_reg6.w;\n" }); + } + } + + return uc_planes; +} + void GLVertexDecompilerThread::insertInputs(std::stringstream & OS, const std::vector& inputs) { std::vector> input_data; @@ -59,7 +109,7 @@ void GLVertexDecompilerThread::insertInputs(std::stringstream & OS, const std::v std::sort(input_data.begin(), input_data.end()); int location = 1; - for (const std::tuple item : input_data) + for (const std::tuple& item : input_data) { for (const ParamType &PT : inputs) { @@ -68,7 +118,7 @@ void GLVertexDecompilerThread::insertInputs(std::stringstream & OS, const std::v if (PI.name == std::get<1>(item)) { bool is_int = false; - for (auto &attrib : rsx_vertex_program.rsx_vertex_inputs) + for (const auto &attrib : rsx_vertex_program.rsx_vertex_inputs) { if (attrib.location == std::get<0>(item)) { @@ -83,6 +133,11 @@ void GLVertexDecompilerThread::insertInputs(std::stringstream & OS, const std::v } } } + + for (const auto& uc : get_user_clip_planes(rsx_vertex_program)) + { + OS << uc.first; + } } void GLVertexDecompilerThread::insertConstants(std::stringstream & OS, const std::vector & constants) @@ -121,9 +176,9 @@ static const reg_info reg_table[] = { "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", false }, - { "gl_ClipDistance[1]", false, "dst_reg5", ".z", false }, - { "gl_ClipDistance[2]", false, "dst_reg5", ".w", false }, + //{ "gl_ClipDistance[0]", false, "dst_reg5", ".y", false }, + //{ "gl_ClipDistance[1]", false, "dst_reg5", ".z", false }, + //{ "gl_ClipDistance[2]", false, "dst_reg5", ".w", false }, { "gl_PointSize", false, "dst_reg6", ".x", false }, //Disable user clip planes until they are properly handled //{ "gl_ClipDistance[3]", false, "dst_reg6", ".y", false }, @@ -143,7 +198,7 @@ static const reg_info reg_table[] = void GLVertexDecompilerThread::insertOutputs(std::stringstream & OS, const std::vector & outputs) { - for (auto &i : reg_table) + for (const auto &i : reg_table) { if (m_parr.HasParam(PF_PARAM_NONE, "vec4", i.src_reg) && i.need_declare) { @@ -196,7 +251,7 @@ void GLVertexDecompilerThread::insertMainStart(std::stringstream & OS) OS << "{" << std::endl; // Declare inside main function - for (const ParamType PT : m_parr.params[PF_PARAM_NONE]) + for (const ParamType& PT : m_parr.params[PF_PARAM_NONE]) { for (const ParamItem &PI : PT.items) { @@ -227,11 +282,17 @@ void GLVertexDecompilerThread::insertMainStart(std::stringstream & OS) void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS) { - for (auto &i : reg_table) + for (const auto &i : reg_table) { if (m_parr.HasParam(PF_PARAM_NONE, "vec4", i.src_reg)) OS << " " << i.name << " = " << i.src_reg << i.src_reg_mask << ";" << std::endl; } + + for (const auto& uc : get_user_clip_planes(rsx_vertex_program)) + { + OS << uc.second; + } + OS << " gl_Position = gl_Position * scaleOffsetMat;" << std::endl; OS << "}" << std::endl; }