[GPU] Move common-face polygon offset to draw_util
This commit is contained in:
parent
8d07c79897
commit
10ec47e1fe
|
@ -1411,7 +1411,6 @@ bool PipelineCache::GetCurrentStateDescription(
|
||||||
// rasterization will be disabled externally, or the draw call will be dropped
|
// rasterization will be disabled externally, or the draw call will be dropped
|
||||||
// early if the vertex shader doesn't export to memory.
|
// early if the vertex shader doesn't export to memory.
|
||||||
bool cull_front, cull_back;
|
bool cull_front, cull_back;
|
||||||
float poly_offset = 0.0f, poly_offset_scale = 0.0f;
|
|
||||||
if (primitive_polygonal) {
|
if (primitive_polygonal) {
|
||||||
description_out.front_counter_clockwise = pa_su_sc_mode_cntl.face == 0;
|
description_out.front_counter_clockwise = pa_su_sc_mode_cntl.face == 0;
|
||||||
cull_front = pa_su_sc_mode_cntl.cull_front != 0;
|
cull_front = pa_su_sc_mode_cntl.cull_front != 0;
|
||||||
|
@ -1435,10 +1434,6 @@ bool PipelineCache::GetCurrentStateDescription(
|
||||||
xenos::PolygonType::kTriangles) {
|
xenos::PolygonType::kTriangles) {
|
||||||
description_out.fill_mode_wireframe = 1;
|
description_out.fill_mode_wireframe = 1;
|
||||||
}
|
}
|
||||||
if (!edram_rov_used && pa_su_sc_mode_cntl.poly_offset_front_enable) {
|
|
||||||
poly_offset = regs[XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_OFFSET].f32;
|
|
||||||
poly_offset_scale = regs[XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_SCALE].f32;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!cull_back) {
|
if (!cull_back) {
|
||||||
// Back faces aren't culled.
|
// Back faces aren't culled.
|
||||||
|
@ -1446,13 +1441,6 @@ bool PipelineCache::GetCurrentStateDescription(
|
||||||
xenos::PolygonType::kTriangles) {
|
xenos::PolygonType::kTriangles) {
|
||||||
description_out.fill_mode_wireframe = 1;
|
description_out.fill_mode_wireframe = 1;
|
||||||
}
|
}
|
||||||
// Prefer front depth bias because in general, front faces are the ones
|
|
||||||
// that are rendered (except for shadow volumes).
|
|
||||||
if (!edram_rov_used && pa_su_sc_mode_cntl.poly_offset_back_enable &&
|
|
||||||
poly_offset == 0.0f && poly_offset_scale == 0.0f) {
|
|
||||||
poly_offset = regs[XE_GPU_REG_PA_SU_POLY_OFFSET_BACK_OFFSET].f32;
|
|
||||||
poly_offset_scale = regs[XE_GPU_REG_PA_SU_POLY_OFFSET_BACK_SCALE].f32;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (pa_su_sc_mode_cntl.poly_mode != xenos::PolygonModeEnable::kDualMode) {
|
if (pa_su_sc_mode_cntl.poly_mode != xenos::PolygonModeEnable::kDualMode) {
|
||||||
description_out.fill_mode_wireframe = 0;
|
description_out.fill_mode_wireframe = 0;
|
||||||
|
@ -1461,24 +1449,23 @@ bool PipelineCache::GetCurrentStateDescription(
|
||||||
// Filled front faces only, without culling.
|
// Filled front faces only, without culling.
|
||||||
cull_front = false;
|
cull_front = false;
|
||||||
cull_back = false;
|
cull_back = false;
|
||||||
if (!edram_rov_used && pa_su_sc_mode_cntl.poly_offset_para_enable) {
|
|
||||||
poly_offset = regs[XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_OFFSET].f32;
|
|
||||||
poly_offset_scale = regs[XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_SCALE].f32;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!edram_rov_used) {
|
if (!edram_rov_used) {
|
||||||
float poly_offset_host_scale = draw_util::GetD3D10PolygonOffsetFactor(
|
float polygon_offset, polygon_offset_scale;
|
||||||
|
draw_util::GetPreferredFacePolygonOffset(
|
||||||
|
regs, primitive_polygonal, polygon_offset_scale, polygon_offset);
|
||||||
|
float polygon_offset_host_scale = draw_util::GetD3D10PolygonOffsetFactor(
|
||||||
regs.Get<reg::RB_DEPTH_INFO>().depth_format, true);
|
regs.Get<reg::RB_DEPTH_INFO>().depth_format, true);
|
||||||
// Using ceil here just in case a game wants the offset but passes a value
|
// Using ceil here just in case a game wants the offset but passes a value
|
||||||
// that is too small - it's better to apply more offset than to make depth
|
// that is too small - it's better to apply more offset than to make depth
|
||||||
// fighting worse or to disable the offset completely (Direct3D 12 takes an
|
// fighting worse or to disable the offset completely (Direct3D 12 takes an
|
||||||
// integer value).
|
// integer value).
|
||||||
description_out.depth_bias =
|
description_out.depth_bias =
|
||||||
int32_t(std::ceil(std::abs(poly_offset * poly_offset_host_scale))) *
|
int32_t(
|
||||||
(poly_offset < 0.0f ? -1 : 1);
|
std::ceil(std::abs(polygon_offset * polygon_offset_host_scale))) *
|
||||||
// "slope computed in subpixels ([...] 1/16)" - R5xx Acceleration.
|
(polygon_offset < 0.0f ? -1 : 1);
|
||||||
description_out.depth_bias_slope_scaled =
|
description_out.depth_bias_slope_scaled =
|
||||||
poly_offset_scale * xenos::kPolygonOffsetScaleSubpixelUnit;
|
polygon_offset_scale * xenos::kPolygonOffsetScaleSubpixelUnit;
|
||||||
}
|
}
|
||||||
if (tessellated && cvars::d3d12_tessellation_wireframe) {
|
if (tessellated && cvars::d3d12_tessellation_wireframe) {
|
||||||
description_out.fill_mode_wireframe = 1;
|
description_out.fill_mode_wireframe = 1;
|
||||||
|
|
|
@ -68,6 +68,36 @@ const int8_t kD3D10StandardSamplePositions2x[2][2] = {{4, 4}, {-4, -4}};
|
||||||
const int8_t kD3D10StandardSamplePositions4x[4][2] = {
|
const int8_t kD3D10StandardSamplePositions4x[4][2] = {
|
||||||
{-2, -6}, {6, -2}, {-6, 2}, {2, 6}};
|
{-2, -6}, {6, -2}, {-6, 2}, {2, 6}};
|
||||||
|
|
||||||
|
void GetPreferredFacePolygonOffset(const RegisterFile& regs,
|
||||||
|
bool primitive_polygonal, float& scale_out,
|
||||||
|
float& offset_out) {
|
||||||
|
float scale = 0.0f, offset = 0.0f;
|
||||||
|
auto pa_su_sc_mode_cntl = regs.Get<reg::PA_SU_SC_MODE_CNTL>();
|
||||||
|
if (primitive_polygonal) {
|
||||||
|
// Prefer the front polygon offset because in general, front faces are the
|
||||||
|
// ones that are rendered (except for shadow volumes).
|
||||||
|
if (pa_su_sc_mode_cntl.poly_offset_front_enable &&
|
||||||
|
!pa_su_sc_mode_cntl.cull_front) {
|
||||||
|
scale = regs[XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_SCALE].f32;
|
||||||
|
offset = regs[XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_OFFSET].f32;
|
||||||
|
}
|
||||||
|
if (pa_su_sc_mode_cntl.poly_offset_back_enable &&
|
||||||
|
!pa_su_sc_mode_cntl.cull_back && !scale && !offset) {
|
||||||
|
scale = regs[XE_GPU_REG_PA_SU_POLY_OFFSET_BACK_SCALE].f32;
|
||||||
|
offset = regs[XE_GPU_REG_PA_SU_POLY_OFFSET_BACK_OFFSET].f32;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Non-triangle primitives use the front offset, but it's toggled via
|
||||||
|
// poly_offset_para_enable.
|
||||||
|
if (pa_su_sc_mode_cntl.poly_offset_para_enable) {
|
||||||
|
scale = regs[XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_SCALE].f32;
|
||||||
|
offset = regs[XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_OFFSET].f32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scale_out = scale;
|
||||||
|
offset_out = offset;
|
||||||
|
}
|
||||||
|
|
||||||
bool IsPixelShaderNeededWithRasterization(const Shader& shader,
|
bool IsPixelShaderNeededWithRasterization(const Shader& shader,
|
||||||
const RegisterFile& regs) {
|
const RegisterFile& regs) {
|
||||||
assert_true(shader.type() == xenos::ShaderType::kPixel);
|
assert_true(shader.type() == xenos::ShaderType::kPixel);
|
||||||
|
|
|
@ -122,6 +122,16 @@ constexpr float GetD3D10PolygonOffsetFactor(
|
||||||
return float24_as_0_to_0_5 ? kFloat24Scale * 0.5f : kFloat24Scale;
|
return float24_as_0_to_0_5 ? kFloat24Scale * 0.5f : kFloat24Scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// For hosts not supporting separate front and back polygon offsets, returns the
|
||||||
|
// polygon offset for the face which likely needs the offset the most (and that
|
||||||
|
// will not be culled). The values returned will have the units of the original
|
||||||
|
// registers (the scale is for 1/16 subpixels, multiply by
|
||||||
|
// xenos::kPolygonOffsetScaleSubpixelUnit outside if the value for pixels is
|
||||||
|
// needed).
|
||||||
|
void GetPreferredFacePolygonOffset(const RegisterFile& regs,
|
||||||
|
bool primitive_polygonal, float& scale_out,
|
||||||
|
float& offset_out);
|
||||||
|
|
||||||
inline bool DoesCoverageDependOnAlpha(reg::RB_COLORCONTROL rb_colorcontrol) {
|
inline bool DoesCoverageDependOnAlpha(reg::RB_COLORCONTROL rb_colorcontrol) {
|
||||||
return (rb_colorcontrol.alpha_test_enable &&
|
return (rb_colorcontrol.alpha_test_enable &&
|
||||||
rb_colorcontrol.alpha_func != xenos::CompareFunction::kAlways) ||
|
rb_colorcontrol.alpha_func != xenos::CompareFunction::kAlways) ||
|
||||||
|
|
Loading…
Reference in New Issue