mirror of https://github.com/RPCS3/rpcs3.git
rsx: Fix clip space computations
This commit is contained in:
parent
75964c686f
commit
98cf72e0fb
|
@ -87,7 +87,7 @@ void D3D12GSRender::upload_and_bind_scale_offset_matrix(size_t descriptorIndex)
|
||||||
// Scale offset buffer
|
// Scale offset buffer
|
||||||
// Separate constant buffer
|
// Separate constant buffer
|
||||||
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + 512));
|
void *mapped_buffer = m_buffer_data.map<void>(CD3DX12_RANGE(heap_offset, heap_offset + 512));
|
||||||
fill_scale_offset_data(mapped_buffer, true, false);
|
fill_scale_offset_data(mapped_buffer, true);
|
||||||
fill_user_clip_data((char*)mapped_buffer + 64);
|
fill_user_clip_data((char*)mapped_buffer + 64);
|
||||||
fill_fragment_state_buffer((char *)mapped_buffer + 128, 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));
|
m_buffer_data.unmap(CD3DX12_RANGE(heap_offset, heap_offset + 512));
|
||||||
|
|
|
@ -787,7 +787,7 @@ bool GLGSRender::load_program()
|
||||||
auto mapping = m_scale_offset_buffer->alloc_from_heap(512, m_uniform_buffer_offset_align);
|
auto mapping = m_scale_offset_buffer->alloc_from_heap(512, m_uniform_buffer_offset_align);
|
||||||
buf = static_cast<u8*>(mapping.first);
|
buf = static_cast<u8*>(mapping.first);
|
||||||
scale_offset_offset = mapping.second;
|
scale_offset_offset = mapping.second;
|
||||||
fill_scale_offset_data(buf, false, true);
|
fill_scale_offset_data(buf, false);
|
||||||
fill_user_clip_data((char *)buf + 64);
|
fill_user_clip_data((char *)buf + 64);
|
||||||
|
|
||||||
if (m_transform_constants_dirty)
|
if (m_transform_constants_dirty)
|
||||||
|
|
|
@ -375,6 +375,20 @@ void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS)
|
||||||
OS << " front_spec_color = dst_reg2;\n";
|
OS << " front_spec_color = dst_reg2;\n";
|
||||||
|
|
||||||
OS << " gl_Position = gl_Position * scaleOffsetMat;" << std::endl;
|
OS << " gl_Position = gl_Position * scaleOffsetMat;" << std::endl;
|
||||||
|
|
||||||
|
//Since our clip_space is symetrical [-1, 1] we map it to linear space using the eqn:
|
||||||
|
//ln = (clip * 2) - 1 to fully utilize the 0-1 range of the depth buffer
|
||||||
|
//RSX matrices passed already map to the [0, 1] range but mapping to classic OGL requires that we undo this step
|
||||||
|
//This can be made unnecessary using the call glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE).
|
||||||
|
//However, ClipControl only made it to opengl core in ver 4.5 though, so this is a workaround.
|
||||||
|
|
||||||
|
//NOTE: It is completely valid for games to use very large w values, causing the post-multiplied z to be in the hundreds
|
||||||
|
//It is therefore critical that this step is done post-transform and the result re-scaled by w
|
||||||
|
//SEE Naruto: UNS
|
||||||
|
|
||||||
|
OS << " float ndc_z = gl_Position.z / gl_Position.w;" << std::endl;
|
||||||
|
OS << " ndc_z = (ndc_z * 2.) - 1.;" << std::endl;
|
||||||
|
OS << " gl_Position.z = ndc_z * gl_Position.w;" << std::endl;
|
||||||
OS << "}" << std::endl;
|
OS << "}" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -506,7 +506,7 @@ namespace rsx
|
||||||
return "rsx::thread";
|
return "rsx::thread";
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread::fill_scale_offset_data(void *buffer, bool flip_y, bool symmetrical_z) const
|
void thread::fill_scale_offset_data(void *buffer, bool flip_y) const
|
||||||
{
|
{
|
||||||
int clip_w = rsx::method_registers.surface_clip_width();
|
int clip_w = rsx::method_registers.surface_clip_width();
|
||||||
int clip_h = rsx::method_registers.surface_clip_height();
|
int clip_h = rsx::method_registers.surface_clip_height();
|
||||||
|
@ -523,20 +523,6 @@ namespace rsx
|
||||||
|
|
||||||
float scale_z = rsx::method_registers.viewport_scale_z();
|
float scale_z = rsx::method_registers.viewport_scale_z();
|
||||||
float offset_z = rsx::method_registers.viewport_offset_z();
|
float offset_z = rsx::method_registers.viewport_offset_z();
|
||||||
|
|
||||||
if (symmetrical_z)
|
|
||||||
{
|
|
||||||
//Since our clip_space is symetrical [-1, 1] we map it to linear space using the eqn:
|
|
||||||
//ln = (clip * 2) - 1 to fully utilize the 0-1 range of the depth buffer
|
|
||||||
//RSX matrices passed already map to the [0, 1] range but mapping to classic OGL
|
|
||||||
//Requires that we undo this step
|
|
||||||
//This can be made unnecessary using the call glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE).
|
|
||||||
//However, ClipControl only made it to opengl core in ver 4.5 though, so this is a workaround.
|
|
||||||
|
|
||||||
offset_z -= 1.f;
|
|
||||||
scale_z *= 2.f;
|
|
||||||
}
|
|
||||||
|
|
||||||
float one = 1.f;
|
float one = 1.f;
|
||||||
|
|
||||||
stream_vector(buffer, (u32&)scale_x, 0, 0, (u32&)offset_x);
|
stream_vector(buffer, (u32&)scale_x, 0, 0, (u32&)offset_x);
|
||||||
|
|
|
@ -244,9 +244,9 @@ namespace rsx
|
||||||
/**
|
/**
|
||||||
* Fill buffer with 4x4 scale offset matrix.
|
* Fill buffer with 4x4 scale offset matrix.
|
||||||
* Vertex shader's position is to be multiplied by this matrix.
|
* Vertex shader's position is to be multiplied by this matrix.
|
||||||
* if is_d3d is set, the matrix is modified to use d3d convention.
|
* if flip_y is set, the matrix is modified to use d3d convention.
|
||||||
*/
|
*/
|
||||||
void fill_scale_offset_data(void *buffer, bool flip_y, bool symmetrical_z) const;
|
void fill_scale_offset_data(void *buffer, bool flip_y) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill buffer with user clip information
|
* Fill buffer with user clip information
|
||||||
|
|
|
@ -1492,7 +1492,7 @@ bool VKGSRender::load_program()
|
||||||
* NOTE: While VK's coord system resembles GLs, the clip volume is no longer symetrical in z
|
* 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)
|
* Its like D3D without the flip in y (depending on how you build the spir-v)
|
||||||
*/
|
*/
|
||||||
fill_scale_offset_data(buf, false, false);
|
fill_scale_offset_data(buf, false);
|
||||||
fill_user_clip_data(buf + 64);
|
fill_user_clip_data(buf + 64);
|
||||||
|
|
||||||
m_uniform_buffer_ring_info.unmap();
|
m_uniform_buffer_ring_info.unmap();
|
||||||
|
|
Loading…
Reference in New Issue