[GPU] Rename PrimitiveTwoFaced to PrimitivePolygonal, add rects to it and ignore fill modes for non-polygons

This commit is contained in:
Triang3l 2020-11-19 23:55:49 +03:00
parent 3ff5965133
commit 44a3f200c3
6 changed files with 38 additions and 28 deletions

View File

@ -1876,14 +1876,14 @@ bool D3D12CommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
!pixel_shader->memexport_stream_constants().empty();
bool memexport_used = memexport_used_vertex || memexport_used_pixel;
bool primitive_two_faced =
xenos::IsPrimitiveTwoFaced(tessellated, primitive_type);
bool primitive_polygonal =
xenos::IsPrimitivePolygonal(tessellated, primitive_type);
auto sq_program_cntl = regs.Get<reg::SQ_PROGRAM_CNTL>();
auto pa_su_sc_mode_cntl = regs.Get<reg::PA_SU_SC_MODE_CNTL>();
if (!memexport_used_vertex &&
(sq_program_cntl.vs_export_mode ==
xenos::VertexShaderExportMode::kMultipass ||
(primitive_two_faced && pa_su_sc_mode_cntl.cull_front &&
(primitive_polygonal && pa_su_sc_mode_cntl.cull_front &&
pa_su_sc_mode_cntl.cull_back))) {
// All faces are culled - can't be expressed in the pipeline.
return true;
@ -2027,11 +2027,11 @@ bool D3D12CommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
scissor.height *= pixel_size_y;
// Update viewport, scissor, blend factor and stencil reference.
UpdateFixedFunctionState(viewport_info, scissor, primitive_two_faced);
UpdateFixedFunctionState(viewport_info, scissor, primitive_polygonal);
// Update system constants before uploading them.
UpdateSystemConstantValues(
memexport_used, primitive_two_faced, line_loop_closing_index,
memexport_used, primitive_polygonal, line_loop_closing_index,
indexed ? index_buffer_info->endianness : xenos::Endian::kNone,
viewport_info, pixel_size_x, pixel_size_y, used_texture_mask, early_z,
GetCurrentColorMask(pixel_shader), pipeline_render_targets);
@ -2785,7 +2785,7 @@ void D3D12CommandProcessor::ClearCommandAllocatorCache() {
void D3D12CommandProcessor::UpdateFixedFunctionState(
const draw_util::ViewportInfo& viewport_info,
const draw_util::Scissor& scissor, bool primitive_two_faced) {
const draw_util::Scissor& scissor, bool primitive_polygonal) {
#if XE_UI_D3D12_FINE_GRAINED_DRAW_SCOPES
SCOPE_profile_cpu_f("gpu");
#endif // XE_UI_D3D12_FINE_GRAINED_DRAW_SCOPES
@ -2851,7 +2851,7 @@ void D3D12CommandProcessor::UpdateFixedFunctionState(
// choose the back face one only if drawing only back faces.
Register stencil_ref_mask_reg;
auto pa_su_sc_mode_cntl = regs.Get<reg::PA_SU_SC_MODE_CNTL>();
if (primitive_two_faced &&
if (primitive_polygonal &&
regs.Get<reg::RB_DEPTHCONTROL>().backface_enable &&
pa_su_sc_mode_cntl.cull_front && !pa_su_sc_mode_cntl.cull_back) {
stencil_ref_mask_reg = XE_GPU_REG_RB_STENCILREFMASK_BF;
@ -2870,7 +2870,7 @@ void D3D12CommandProcessor::UpdateFixedFunctionState(
}
void D3D12CommandProcessor::UpdateSystemConstantValues(
bool shared_memory_is_uav, bool primitive_two_faced,
bool shared_memory_is_uav, bool primitive_polygonal,
uint32_t line_loop_closing_index, xenos::Endian index_endian,
const draw_util::ViewportInfo& viewport_info, uint32_t pixel_size_x,
uint32_t pixel_size_y, uint32_t used_texture_mask, bool early_z,
@ -2983,9 +2983,9 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
flags |= (pa_cl_clip_cntl.value & 0b111111)
<< DxbcShaderTranslator::kSysFlag_UserClipPlane0_Shift;
}
// Whether SV_IsFrontFace matters.
if (primitive_two_faced) {
flags |= DxbcShaderTranslator::kSysFlag_PrimitiveTwoFaced;
// Whether the primitive is polygonal and SV_IsFrontFace matters.
if (primitive_polygonal) {
flags |= DxbcShaderTranslator::kSysFlag_PrimitivePolygonal;
}
// Primitive killing condition.
if (pa_cl_clip_cntl.vtx_kill_or) {
@ -3082,7 +3082,7 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
// to do memexport.
if (sq_program_cntl.vs_export_mode ==
xenos::VertexShaderExportMode::kMultipass ||
(primitive_two_faced && pa_su_sc_mode_cntl.cull_front &&
(primitive_polygonal && pa_su_sc_mode_cntl.cull_front &&
pa_su_sc_mode_cntl.cull_back)) {
float nan_value = std::nanf("");
for (uint32_t i = 0; i < 3; ++i) {
@ -3275,7 +3275,7 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
// are used.
float poly_offset_front_scale = 0.0f, poly_offset_front_offset = 0.0f;
float poly_offset_back_scale = 0.0f, poly_offset_back_offset = 0.0f;
if (primitive_two_faced) {
if (primitive_polygonal) {
if (pa_su_sc_mode_cntl.poly_offset_front_enable) {
poly_offset_front_scale =
regs[XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_SCALE].f32;
@ -3338,7 +3338,7 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
system_constants_.edram_stencil_front_func_ops != stencil_func_ops;
system_constants_.edram_stencil_front_func_ops = stencil_func_ops;
if (primitive_two_faced && rb_depthcontrol.backface_enable) {
if (primitive_polygonal && rb_depthcontrol.backface_enable) {
dirty |= system_constants_.edram_stencil_back_reference !=
rb_stencilrefmask_bf.stencilref;
system_constants_.edram_stencil_back_reference =

View File

@ -348,9 +348,9 @@ class D3D12CommandProcessor : public CommandProcessor {
void UpdateFixedFunctionState(const draw_util::ViewportInfo& viewport_info,
const draw_util::Scissor& scissor,
bool primitive_two_faced);
bool primitive_polygonal);
void UpdateSystemConstantValues(
bool shared_memory_is_uav, bool primitive_two_faced,
bool shared_memory_is_uav, bool primitive_polygonal,
uint32_t line_loop_closing_index, xenos::Endian index_endian,
const draw_util::ViewportInfo& viewport_info, uint32_t pixel_size_x,
uint32_t pixel_size_y, uint32_t used_texture_mask, bool early_z,

View File

@ -1285,7 +1285,7 @@ bool PipelineCache::GetCurrentStateDescription(
uint32_t(regs.Get<reg::VGT_HOS_CNTL>().tess_mode);
}
bool primitive_two_faced = xenos::IsPrimitiveTwoFaced(
bool primitive_polygonal = xenos::IsPrimitivePolygonal(
host_vertex_shader_type != Shader::HostVertexShaderType::kVertex,
primitive_type);
@ -1305,15 +1305,16 @@ bool PipelineCache::GetCurrentStateDescription(
// Here we also assume that only one side is culled - if two sides are culled,
// the D3D12 command processor will drop such draw early.
bool cull_front, cull_back;
if (primitive_two_faced) {
if (primitive_polygonal) {
cull_front = pa_su_sc_mode_cntl.cull_front != 0;
cull_back = pa_su_sc_mode_cntl.cull_back != 0;
} else {
// Non-polygonal primitives are never culled.
cull_front = false;
cull_back = false;
}
float poly_offset = 0.0f, poly_offset_scale = 0.0f;
if (primitive_two_faced) {
if (primitive_polygonal) {
description_out.front_counter_clockwise = pa_su_sc_mode_cntl.face == 0;
if (cull_front) {
description_out.cull_mode = PipelineCullMode::kFront;
@ -1327,8 +1328,8 @@ bool PipelineCache::GetCurrentStateDescription(
if (!cull_front) {
// Front faces aren't culled.
// Direct3D 12, unfortunately, doesn't support point fill mode.
if (pa_su_sc_mode_cntl.polymode_front_ptype !=
xenos::PolygonType::kTriangles) {
if (primitive_polygonal && pa_su_sc_mode_cntl.polymode_front_ptype !=
xenos::PolygonType::kTriangles) {
description_out.fill_mode_wireframe = 1;
}
if (!edram_rov_used_ && pa_su_sc_mode_cntl.poly_offset_front_enable) {
@ -1338,8 +1339,8 @@ bool PipelineCache::GetCurrentStateDescription(
}
if (!cull_back) {
// Back faces aren't culled.
if (pa_su_sc_mode_cntl.polymode_back_ptype !=
xenos::PolygonType::kTriangles) {
if (primitive_polygonal && pa_su_sc_mode_cntl.polymode_back_ptype !=
xenos::PolygonType::kTriangles) {
description_out.fill_mode_wireframe = 1;
}
// Prefer front depth bias because in general, front faces are the ones
@ -1413,7 +1414,7 @@ bool PipelineCache::GetCurrentStateDescription(
if (rb_depthcontrol.stencil_enable) {
description_out.stencil_enable = 1;
bool stencil_backface_enable =
primitive_two_faced && rb_depthcontrol.backface_enable;
primitive_polygonal && rb_depthcontrol.backface_enable;
// Per-face masks not supported by Direct3D 12, choose the back face
// ones only if drawing only back faces.
Register stencil_ref_mask_reg;

View File

@ -770,7 +770,7 @@ void DxbcShaderTranslator::StartPixelShader() {
uint32_t(CbufferRegister::kSystemConstants),
kSysConst_Flags_Vec)
.Select(kSysConst_Flags_Comp),
DxbcSrc::LU(kSysFlag_PrimitiveTwoFaced));
DxbcSrc::LU(kSysFlag_PrimitivePolygonal));
DxbcOpIf(true, DxbcSrc::R(param_gen_temp, DxbcSrc::kZZZZ));
{
// Negate modifier flips the sign bit even for 0 - set it to minus for

View File

@ -124,7 +124,7 @@ class DxbcShaderTranslator : public ShaderTranslator {
kSysFlag_UserClipPlane4_Shift,
kSysFlag_UserClipPlane5_Shift,
kSysFlag_KillIfAnyVertexKilled_Shift,
kSysFlag_PrimitiveTwoFaced_Shift,
kSysFlag_PrimitivePolygonal_Shift,
kSysFlag_AlphaPassIfLess_Shift,
kSysFlag_AlphaPassIfEqual_Shift,
kSysFlag_AlphaPassIfGreater_Shift,
@ -165,7 +165,7 @@ class DxbcShaderTranslator : public ShaderTranslator {
kSysFlag_UserClipPlane4 = 1u << kSysFlag_UserClipPlane4_Shift,
kSysFlag_UserClipPlane5 = 1u << kSysFlag_UserClipPlane5_Shift,
kSysFlag_KillIfAnyVertexKilled = 1u << kSysFlag_KillIfAnyVertexKilled_Shift,
kSysFlag_PrimitiveTwoFaced = 1u << kSysFlag_PrimitiveTwoFaced_Shift,
kSysFlag_PrimitivePolygonal = 1u << kSysFlag_PrimitivePolygonal_Shift,
kSysFlag_AlphaPassIfLess = 1u << kSysFlag_AlphaPassIfLess_Shift,
kSysFlag_AlphaPassIfEqual = 1u << kSysFlag_AlphaPassIfEqual_Shift,
kSysFlag_AlphaPassIfGreater = 1u << kSysFlag_AlphaPassIfGreater_Shift,

View File

@ -64,7 +64,15 @@ enum class PrimitiveType : uint32_t {
kQuadPatch = 0x12,
};
inline bool IsPrimitiveTwoFaced(bool tessellated, PrimitiveType type) {
// Polygonal primitive types (not including points and lines) are rasterized as
// triangles, have front and back faces, and also support face culling and fill
// modes (polymode_front_ptype, polymode_back_ptype). Other primitive types are
// always "front" (but don't support front face and back face culling, according
// to OpenGL and Vulkan specifications - even if glCullFace is
// GL_FRONT_AND_BACK, points and lines are still drawn), and may in some cases
// use the "para" registers instead of "front" or "back" (for "parallelogram" -
// like poly_offset_para_enable).
constexpr bool IsPrimitivePolygonal(bool tessellated, PrimitiveType type) {
if (tessellated && (type == PrimitiveType::kTrianglePatch ||
type == PrimitiveType::kQuadPatch)) {
return true;
@ -74,6 +82,7 @@ inline bool IsPrimitiveTwoFaced(bool tessellated, PrimitiveType type) {
case PrimitiveType::kTriangleFan:
case PrimitiveType::kTriangleStrip:
case PrimitiveType::kTriangleWithWFlags:
case PrimitiveType::kRectangleList:
case PrimitiveType::kQuadList:
case PrimitiveType::kQuadStrip:
case PrimitiveType::kPolygon: