diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp index 25eba295c3..f145dee081 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Buffer.cpp @@ -54,8 +54,8 @@ namespace { u32 element_size = rsx::get_vertex_type_size_on_host(info.type(), info.size()); D3D12_SHADER_RESOURCE_VIEW_DESC vertex_buffer_view = { - get_vertex_attribute_format(info.type(), info.size()), D3D12_SRV_DIMENSION_BUFFER, - get_component_mapping_from_vector_size(info.type(), info.size())}; + get_vertex_attribute_format(info.type(), info.size()), D3D12_SRV_DIMENSION_BUFFER, + get_component_mapping_from_vector_size(info.type(), info.size())}; vertex_buffer_view.Buffer.FirstElement = offset_in_vertex_buffers_buffer / element_size; vertex_buffer_view.Buffer.NumElements = buffer_size / element_size; return vertex_buffer_view; @@ -65,7 +65,7 @@ namespace { u32 element_size = rsx::get_vertex_type_size_on_host(type, size); D3D12_SHADER_RESOURCE_VIEW_DESC vertex_buffer_view = {get_vertex_attribute_format(type, size), - D3D12_SRV_DIMENSION_BUFFER, get_component_mapping_from_vector_size(type, size)}; + D3D12_SRV_DIMENSION_BUFFER, get_component_mapping_from_vector_size(type, size)}; vertex_buffer_view.Buffer.FirstElement = offset_in_vertex_buffers_buffer / element_size; vertex_buffer_view.Buffer.NumElements = buffer_size / element_size; return vertex_buffer_view; @@ -87,8 +87,10 @@ void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex) // Scale offset buffer // Separate constant buffer void *mapped_buffer = m_buffer_data.map(CD3DX12_RANGE(heap_offset, heap_offset + 512)); - fill_scale_offset_data(mapped_buffer); - fill_fragment_state_buffer((char *)mapped_buffer + 64, m_fragment_program); + 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); 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 37a79848c2..de5c0afaf7 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12FragmentProgramDecompiler.cpp @@ -38,6 +38,7 @@ void D3D12FragmentDecompiler::insertHeader(std::stringstream & OS) OS << "cbuffer SCALE_OFFSET : register(b0)" << std::endl; OS << "{" << std::endl; OS << " float4x4 scaleOffsetMat;" << std::endl; + OS << " int userClip[8];" << std::endl; OS << " float fog_param0;\n"; OS << " float fog_param1;\n"; OS << " int isAlphaTested;" << std::endl; @@ -55,7 +56,7 @@ void D3D12FragmentDecompiler::insertIntputs(std::stringstream & OS) OS << " float4 spec_color : COLOR1;" << std::endl; OS << " float4 dst_reg3 : COLOR2;" << std::endl; OS << " float4 dst_reg4 : COLOR3;" << std::endl; - OS << " float fogc : FOG;" << std::endl; + OS << " float4 fogc : FOG;" << std::endl; OS << " float4 tc9 : TEXCOORD9;" << std::endl; OS << " float4 tc0 : TEXCOORD0;" << std::endl; OS << " float4 tc1 : TEXCOORD1;" << std::endl; @@ -66,6 +67,8 @@ void D3D12FragmentDecompiler::insertIntputs(std::stringstream & OS) OS << " float4 tc6 : TEXCOORD6;" << std::endl; OS << " float4 tc7 : TEXCOORD7;" << std::endl; OS << " float4 tc8 : TEXCOORD8;" << std::endl; + OS << " float4 dst_userClip0 : SV_ClipDistance0;" << std::endl; + OS << " float4 dst_userClip1 : SV_ClipDistance1;" << std::endl; OS << "};" << std::endl; } @@ -154,22 +157,22 @@ namespace switch (mode) { case rsx::fog_mode::linear: - OS << " float4 fogc = float4(fog_param1 * In.fogc + (fog_param0 - 1.), fog_param1 * In.fogc + (fog_param0 - 1.), 0., 0.);\n"; + OS << " float4 fogc = float4(fog_param1 * In.fogc.x + (fog_param0 - 1.), fog_param1 * In.fogc.x + (fog_param0 - 1.), 0., 0.);\n"; break; case rsx::fog_mode::exponential: - OS << " float4 fogc = float4(11.084 * (fog_param1 * In.fogc + fog_param0 - 1.5), exp(11.084 * (fog_param1 * In.fogc + fog_param0 - 1.5)), 0., 0.);\n"; + OS << " float4 fogc = float4(11.084 * (fog_param1 * In.fogc.x + fog_param0 - 1.5), exp(11.084 * (fog_param1 * In.fogc.x + fog_param0 - 1.5)), 0., 0.);\n"; break; case rsx::fog_mode::exponential2: - OS << " float4 fogc = float4(4.709 * (fog_param1 * In.fogc + fog_param0 - 1.5), exp(-pow(4.709 * (fog_param1 * In.fogc + fog_param0 - 1.5)), 2.)), 0., 0.);\n"; + OS << " float4 fogc = float4(4.709 * (fog_param1 * In.fogc.x + fog_param0 - 1.5), exp(-pow(4.709 * (fog_param1 * In.fogc.x + fog_param0 - 1.5)), 2.)), 0., 0.);\n"; break; case rsx::fog_mode::linear_abs: - OS << " float4 fogc = float4(fog_param1 * abs(In.fogc) + (fog_param0 - 1.), fog_param1 * abs(In.fogc) + (fog_param0 - 1.), 0., 0.);\n"; + OS << " float4 fogc = float4(fog_param1 * abs(In.fogc.x) + (fog_param0 - 1.), fog_param1 * abs(In.fogc.x) + (fog_param0 - 1.), 0., 0.);\n"; break; case rsx::fog_mode::exponential_abs: - OS << " float4 fogc = float4(11.084 * (fog_param1 * abs(In.fogc) + fog_param0 - 1.5), exp(11.084 * (fog_param1 * abs(In.fogc) + fog_param0 - 1.5)), 0., 0.);\n"; + OS << " float4 fogc = float4(11.084 * (fog_param1 * abs(In.fogc.x) + fog_param0 - 1.5), exp(11.084 * (fog_param1 * abs(In.fogc.x) + fog_param0 - 1.5)), 0., 0.);\n"; break; case rsx::fog_mode::exponential2_abs: - OS << " float4 fogc = float4(4.709 * (fog_param1 * abs(In.fogc) + fog_param0 - 1.5), exp(-pow(4.709 * (fog_param1 * abs(In.fogc) + fog_param0 - 1.5)), 2.)), 0., 0.);\n"; + OS << " float4 fogc = float4(4.709 * (fog_param1 * abs(In.fogc.x) + fog_param0 - 1.5), exp(-pow(4.709 * (fog_param1 * abs(In.fogc.x) + fog_param0 - 1.5)), 2.)), 0., 0.);\n"; break; default: OS << " float4 fogc = float4(0., 0., 0., 0.);\n"; diff --git a/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp b/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp index f1db01bc6e..0c689b3079 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12VertexProgramDecompiler.cpp @@ -31,6 +31,7 @@ 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 << " float fog_param0;" << std::endl; OS << " float fog_param1;" << std::endl; OS << " int isAlphaTested;" << std::endl; @@ -93,7 +94,7 @@ void D3D12VertexProgramDecompiler::insertOutputs(std::stringstream & OS, const s OS << " float4 dst_reg2 : COLOR1;" << std::endl; OS << " float4 dst_reg3 : COLOR2;" << std::endl; OS << " float4 dst_reg4 : COLOR3;" << std::endl; - OS << " float dst_reg5 : FOG;" << std::endl; + OS << " float4 dst_reg5 : FOG;" << std::endl; OS << " float4 dst_reg6 : TEXCOORD9;" << std::endl; OS << " float4 dst_reg7 : TEXCOORD0;" << std::endl; OS << " float4 dst_reg8 : TEXCOORD1;" << std::endl; @@ -104,6 +105,8 @@ void D3D12VertexProgramDecompiler::insertOutputs(std::stringstream & OS, const s OS << " float4 dst_reg13 : TEXCOORD6;" << std::endl; OS << " float4 dst_reg14 : TEXCOORD7;" << std::endl; OS << " float4 dst_reg15 : TEXCOORD8;" << std::endl; + OS << " float4 dst_userClip0 : SV_ClipDistance0;" << std::endl; + OS << " float4 dst_userClip1 : SV_ClipDistance1;" << std::endl; OS << "};" << std::endl; } @@ -239,6 +242,20 @@ 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 98410258ca..19eeca992f 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -289,6 +289,13 @@ 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(); } @@ -336,48 +343,6 @@ void GLGSRender::end() std::chrono::time_point program_stop = steady_clock::now(); m_begin_time += (u32)std::chrono::duration_cast(program_stop - program_start).count(); - //Set active user clip planes - const rsx::user_clip_plane_op clip_plane_control[6] = - { - rsx::method_registers.clip_plane_0_enabled(), - rsx::method_registers.clip_plane_1_enabled(), - rsx::method_registers.clip_plane_2_enabled(), - rsx::method_registers.clip_plane_3_enabled(), - rsx::method_registers.clip_plane_4_enabled(), - rsx::method_registers.clip_plane_5_enabled(), - }; - - for (int index = 0; index < 6; ++index) - { - int value = 0; - int location; - - if (m_program->uniforms.has_location("uc_m" + std::to_string(index), &location)) - { - 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; - break; - - case rsx::user_clip_plane_op::greater_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); - }; - if (manually_flush_ring_buffers) { //Use approximations to reseve space. This path is mostly for debug purposes anyway @@ -814,7 +779,8 @@ bool GLGSRender::load_program() auto mapping = m_scale_offset_buffer->alloc_from_heap(512, m_uniform_buffer_offset_align); buf = static_cast(mapping.first); scale_offset_offset = mapping.second; - fill_scale_offset_data(buf, false); + fill_scale_offset_data(buf, false, true); + fill_user_clip_data((char *)buf + 64); if (m_transform_constants_dirty) { diff --git a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp index 0227b24b5e..36cbccfc19 100644 --- a/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLVertexProgram.cpp @@ -34,6 +34,7 @@ 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 << "};" << std::endl; } @@ -124,13 +125,13 @@ 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 * uc_m0", false }, - { "gl_ClipDistance[1]", false, "dst_reg5", ".z * uc_m1", false }, - { "gl_ClipDistance[2]", false, "dst_reg5", ".w * uc_m2", false }, + { "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 }, { "gl_PointSize", false, "dst_reg6", ".x", false }, - { "gl_ClipDistance[3]", false, "dst_reg6", ".y * uc_m3", false }, - { "gl_ClipDistance[4]", false, "dst_reg6", ".z * uc_m4", false }, - { "gl_ClipDistance[5]", false, "dst_reg6", ".w * uc_m5", 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 }, { "tc0", true, "dst_reg7", "", false }, { "tc1", true, "dst_reg8", "", false }, { "tc2", true, "dst_reg9", "", false }, diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index f5fe89830f..b0cddba3dc 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -562,7 +562,7 @@ namespace rsx return "rsx::thread"; } - void thread::fill_scale_offset_data(void *buffer, bool is_d3d) const + void thread::fill_scale_offset_data(void *buffer, bool flip_y, bool symmetrical_z) const { int clip_w = rsx::method_registers.surface_clip_width(); int clip_h = rsx::method_registers.surface_clip_height(); @@ -574,12 +574,12 @@ namespace rsx float scale_y = rsx::method_registers.viewport_scale_y() / (clip_h / 2.f); float offset_y = (rsx::method_registers.viewport_offset_y() - (clip_h / 2.f)); offset_y /= clip_h / 2.f; - if (is_d3d) scale_y *= -1; - if (is_d3d) offset_y *= -1; + if (flip_y) scale_y *= -1; + if (flip_y) offset_y *= -1; float scale_z = rsx::method_registers.viewport_scale_z(); float offset_z = rsx::method_registers.viewport_offset_z(); - if (!is_d3d) offset_z -= .5; + if (symmetrical_z) offset_z -= .5; float one = 1.f; @@ -589,6 +589,46 @@ namespace rsx stream_vector((char*)buffer + 48, 0, 0, 0, (u32&)one); } + void thread::fill_user_clip_data(void *buffer) const + { + const rsx::user_clip_plane_op clip_plane_control[6] = + { + rsx::method_registers.clip_plane_0_enabled(), + rsx::method_registers.clip_plane_1_enabled(), + rsx::method_registers.clip_plane_2_enabled(), + rsx::method_registers.clip_plane_3_enabled(), + rsx::method_registers.clip_plane_4_enabled(), + rsx::method_registers.clip_plane_5_enabled(), + }; + + std::array tmp{}; + 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; + break; + + case rsx::user_clip_plane_op::greater_or_equal: + value = 1.f; + break; + + case rsx::user_clip_plane_op::less_than: + value = -1.f; + break; + } + + tmp[index] = value; + } + stream_vector_from_memory((char*)buffer, tmp.data()); + stream_vector_from_memory((char*)buffer + 16, &tmp[4]); + } + /** * Fill buffer with vertex program constants. * Buffer must be at least 512 float4 wide. @@ -624,12 +664,12 @@ namespace rsx void thread::write_inline_array_to_buffer(void *dst_buffer) { u8* src = - reinterpret_cast(rsx::method_registers.current_draw_clause.inline_vertex_array.data()); + reinterpret_cast(rsx::method_registers.current_draw_clause.inline_vertex_array.data()); u8* dst = (u8*)dst_buffer; size_t bytes_written = 0; while (bytes_written < - rsx::method_registers.current_draw_clause.inline_vertex_array.size() * sizeof(u32)) + rsx::method_registers.current_draw_clause.inline_vertex_array.size() * sizeof(u32)) { for (int index = 0; index < rsx::limits::vertex_count; ++index) { @@ -730,7 +770,7 @@ namespace rsx { const rsx::data_array_format_info& info = state.vertex_arrays_info[index]; result.push_back(vertex_array_buffer{info.type(), info.size(), info.stride(), - get_raw_vertex_buffer(info, state.vertex_data_base_offset(), vertex_ranges), index}); + get_raw_vertex_buffer(info, state.vertex_data_base_offset(), vertex_ranges), index}); continue; } @@ -909,12 +949,12 @@ namespace rsx if (rsx::method_registers.vertex_arrays_info[index].size() > 0) { result.rsx_vertex_inputs.push_back( - {index, - rsx::method_registers.vertex_arrays_info[index].size(), - rsx::method_registers.vertex_arrays_info[index].frequency(), - !!((modulo_mask >> index) & 0x1), - true, - is_int_type(rsx::method_registers.vertex_arrays_info[index].type()), 0}); + {index, + rsx::method_registers.vertex_arrays_info[index].size(), + rsx::method_registers.vertex_arrays_info[index].frequency(), + !!((modulo_mask >> index) & 0x1), + true, + is_int_type(rsx::method_registers.vertex_arrays_info[index].type()), 0}); } else if (vertex_push_buffers[index].vertex_count > 1) { @@ -929,12 +969,12 @@ namespace rsx else if (rsx::method_registers.register_vertex_info[index].size > 0) { result.rsx_vertex_inputs.push_back( - {index, - rsx::method_registers.register_vertex_info[index].size, - rsx::method_registers.register_vertex_info[index].frequency, - !!((modulo_mask >> index) & 0x1), - false, - is_int_type(rsx::method_registers.vertex_arrays_info[index].type()), 0}); + {index, + rsx::method_registers.register_vertex_info[index].size, + rsx::method_registers.register_vertex_info[index].frequency, + !!((modulo_mask >> index) & 0x1), + false, + is_int_type(rsx::method_registers.vertex_arrays_info[index].type()), 0}); } } return result; diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index cd9f640721..c45dc53749 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -309,7 +309,13 @@ namespace rsx * Vertex shader's position is to be multiplied by this matrix. * if is_d3d is set, the matrix is modified to use d3d convention. */ - void fill_scale_offset_data(void *buffer, bool is_d3d = true) const; + void fill_scale_offset_data(void *buffer, bool flip_y, bool symmetrical_z) const; + + /** + * Fill buffer with user clip information + */ + + void fill_user_clip_data(void *buffer) const; /** * Fill buffer with vertex program constants. diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 086fbf9c2b..c8fdf728b1 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -1180,33 +1180,12 @@ bool VKGSRender::load_program() u8 *buf = (u8*)m_uniform_buffer_ring_info.map(scale_offset_offset, 256); - //TODO: Add case for this in RSXThread /** * NOTE: While VK's coord system resembles GLs, the clip volume is no longer symetrical in z * Its like D3D without the flip in y (depending on how you build the spir-v) */ - { - int clip_w = rsx::method_registers.surface_clip_width(); - int clip_h = rsx::method_registers.surface_clip_height(); - - float scale_x = rsx::method_registers.viewport_scale_x() / (clip_w / 2.f); - float offset_x = rsx::method_registers.viewport_offset_x() - (clip_w / 2.f); - offset_x /= clip_w / 2.f; - - float scale_y = rsx::method_registers.viewport_scale_y() / (clip_h / 2.f); - float offset_y = (rsx::method_registers.viewport_offset_y() - (clip_h / 2.f)); - offset_y /= clip_h / 2.f; - - float scale_z = rsx::method_registers.viewport_scale_z(); - float offset_z = rsx::method_registers.viewport_offset_z(); - - float one = 1.f; - - stream_vector(buf, (u32&)scale_x, 0, 0, (u32&)offset_x); - stream_vector((char*)buf + 16, 0, (u32&)scale_y, 0, (u32&)offset_y); - stream_vector((char*)buf + 32, 0, 0, (u32&)scale_z, (u32&)offset_z); - stream_vector((char*)buf + 48, 0, 0, 0, (u32&)one); - } + fill_scale_offset_data(buf, false, false); + fill_user_clip_data(buf + 64); m_uniform_buffer_ring_info.unmap(); diff --git a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp index cebc400a43..24dc08bf0d 100644 --- a/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKVertexProgram.cpp @@ -33,6 +33,7 @@ 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 << "};" << std::endl; vk::glsl::program_input in; @@ -158,16 +159,16 @@ 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 * 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 }, { "gl_PointSize", false, "dst_reg6", ".x", false }, //Disable user clip planes until they are properly handled - //{ "gl_ClipDistance[3]", false, "dst_reg6", ".y", false }, - //{ "gl_ClipDistance[4]", false, "dst_reg6", ".z", false }, - //{ "gl_ClipDistance[5]", false, "dst_reg6", ".w", 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 }, { "tc0", true, "dst_reg7", "", false }, { "tc1", true, "dst_reg8", "", false },