Skip to content

Commit

Permalink
rsx: Fix depth clipping
Browse files Browse the repository at this point in the history
  • Loading branch information
jarveson authored and kd-11 committed Jan 14, 2018
1 parent c5074ba commit 7ca2c44
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 29 deletions.
4 changes: 2 additions & 2 deletions rpcs3/Emu/RSX/D3D12/D3D12GSRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,8 +467,8 @@ void D3D12GSRender::end()
0.f,
(float)clip_w,
(float)clip_h,
rsx::method_registers.clip_min(),
rsx::method_registers.clip_max(),
0.f,
1.f,
};
get_current_resource_storage().command_list->RSSetViewports(1, &viewport);

Expand Down
1 change: 1 addition & 0 deletions rpcs3/Emu/RSX/D3D12/D3D12PipelineState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ void D3D12GSRender::load_program()
D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF,
};
prop.Rasterization = CD3D12_RASTERIZER_DESC;
prop.Rasterization.DepthClipEnable = rsx::method_registers.depth_clip_enabled();

if (rsx::method_registers.cull_face_enabled())
{
Expand Down
10 changes: 0 additions & 10 deletions rpcs3/Emu/RSX/GL/GLGSRender.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1044,16 +1044,6 @@ void GLGSRender::update_draw_state()
if (gl_state.enable(rsx::method_registers.depth_test_enabled(), GL_DEPTH_TEST))
{
gl_state.depth_func(comparison_op(rsx::method_registers.depth_func()));

float range_near = rsx::method_registers.clip_min();
float range_far = rsx::method_registers.clip_max();

//Workaround to preserve depth precision but respect z direction
//Ni no Kuni sets a very restricted z range (0.9x - 1.) and depth reads / tests are broken
if (range_near <= range_far)
gl_state.depth_range(0.f, 1.f);
else
gl_state.depth_range(1.f, 0.f);
}

if (glDepthBoundsEXT && (gl_state.enable(rsx::method_registers.depth_bounds_test_enabled(), GL_DEPTH_BOUNDS_TEST_EXT)))
Expand Down
10 changes: 8 additions & 2 deletions rpcs3/Emu/RSX/RSXThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -790,8 +790,14 @@ namespace rsx
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();
float clip_min = rsx::method_registers.clip_min();
float clip_max = rsx::method_registers.clip_max();

float z_clip_scale = (clip_max + clip_min) == 0.f ? 1.f : (clip_max + clip_min);
float z_offset_scale = (clip_max - clip_min) == 0.f ? 1.f : (clip_max - clip_min);

float scale_z = rsx::method_registers.viewport_scale_z() / z_clip_scale;
float offset_z = rsx::method_registers.viewport_offset_z() / z_offset_scale;
float one = 1.f;

stream_vector(buffer, (u32&)scale_x, 0, 0, (u32&)offset_x);
Expand Down
16 changes: 15 additions & 1 deletion rpcs3/Emu/RSX/rsx_decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -710,20 +710,34 @@ struct registers_decoder<NV4097_SET_ZMIN_MAX_CONTROL>
union
{
u32 raw_value;
bitfield_decoder_t<0, 4> depth_clip_enabled;
bitfield_decoder_t<4, 4> depth_clamp_enabled;
bitfield_decoder_t<8, 4> depth_clip_ignore_w;
} m_data;
public:
decoded_type(u32 raw_value) { m_data.raw_value = raw_value; }

bool depth_clip_enabled() const
{
return bool(m_data.depth_clip_enabled);
}

bool depth_clamp_enabled() const
{
return bool(m_data.depth_clamp_enabled);
}

bool depth_clip_ignore_w() const
{
return bool(m_data.depth_clip_ignore_w);
}
};

static std::string dump(decoded_type &&decoded_values)
{
return "Depth: clamp " + print_boolean(decoded_values.depth_clamp_enabled());
return "Depth: clip_enabled " + print_boolean(decoded_values.depth_clip_enabled()) +
" clamp " + print_boolean(decoded_values.depth_clamp_enabled()) +
" ignore_w " + print_boolean(decoded_values.depth_clip_ignore_w());
}
};

Expand Down
1 change: 1 addition & 0 deletions rpcs3/Emu/RSX/rsx_methods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1159,6 +1159,7 @@ namespace rsx

// Stencil bits init to 00 - Tested with NPEB90184 (never sets the depth_stencil clear values but uses stencil test)
registers[NV4097_SET_ZSTENCIL_CLEAR_VALUE] = 0xffffff00;
registers[NV4097_SET_ZMIN_MAX_CONTROL] = 1;

// CELL_GCM_SURFACE_A8R8G8B8, CELL_GCM_SURFACE_Z24S8 and CELL_GCM_SURFACE_CENTER_1
registers[NV4097_SET_SURFACE_FORMAT] = (8 << 0) | (2 << 5) | (0 << 12) | (1 << 16) | (1 << 24);
Expand Down
26 changes: 12 additions & 14 deletions rpcs3/Emu/RSX/rsx_methods.h
Original file line number Diff line number Diff line change
Expand Up @@ -387,24 +387,12 @@ namespace rsx

f32 clip_min() const
{
f32 depth_min = decode<NV4097_SET_CLIP_MIN>().clip_min();

//Clamp to [0, 1]
if (depth_min < 0.f) return 0.f;
if (depth_min > 1.f) return 1.f;

return depth_min;
return decode<NV4097_SET_CLIP_MIN>().clip_min();
}

f32 clip_max() const
{
f32 depth_max = decode<NV4097_SET_CLIP_MAX>().clip_max();

//Clamp to [0, 1]
if (depth_max < 0.f) return 0.f;
if (depth_max > 1.f) return 1.f;

return depth_max;
return decode<NV4097_SET_CLIP_MAX>().clip_max();
}

bool logic_op_enabled() const
Expand Down Expand Up @@ -1206,6 +1194,16 @@ namespace rsx
{
return decode<NV4097_SET_ZMIN_MAX_CONTROL>().depth_clamp_enabled();
}

bool depth_clip_enabled()
{
return decode<NV4097_SET_ZMIN_MAX_CONTROL>().depth_clip_enabled();
}

bool depth_clip_ignore_w()
{
return decode<NV4097_SET_ZMIN_MAX_CONTROL>().depth_clip_ignore_w();
}
};

extern rsx_state method_registers;
Expand Down

0 comments on commit 7ca2c44

Please sign in to comment.