[GPU] Rename PrimitiveTwoFaced to PrimitivePolygonal, add rects to it and ignore fill modes for non-polygons
This commit is contained in:
parent
3ff5965133
commit
44a3f200c3
|
@ -1876,14 +1876,14 @@ bool D3D12CommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
|
||||||
!pixel_shader->memexport_stream_constants().empty();
|
!pixel_shader->memexport_stream_constants().empty();
|
||||||
bool memexport_used = memexport_used_vertex || memexport_used_pixel;
|
bool memexport_used = memexport_used_vertex || memexport_used_pixel;
|
||||||
|
|
||||||
bool primitive_two_faced =
|
bool primitive_polygonal =
|
||||||
xenos::IsPrimitiveTwoFaced(tessellated, primitive_type);
|
xenos::IsPrimitivePolygonal(tessellated, primitive_type);
|
||||||
auto sq_program_cntl = regs.Get<reg::SQ_PROGRAM_CNTL>();
|
auto sq_program_cntl = regs.Get<reg::SQ_PROGRAM_CNTL>();
|
||||||
auto pa_su_sc_mode_cntl = regs.Get<reg::PA_SU_SC_MODE_CNTL>();
|
auto pa_su_sc_mode_cntl = regs.Get<reg::PA_SU_SC_MODE_CNTL>();
|
||||||
if (!memexport_used_vertex &&
|
if (!memexport_used_vertex &&
|
||||||
(sq_program_cntl.vs_export_mode ==
|
(sq_program_cntl.vs_export_mode ==
|
||||||
xenos::VertexShaderExportMode::kMultipass ||
|
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))) {
|
pa_su_sc_mode_cntl.cull_back))) {
|
||||||
// All faces are culled - can't be expressed in the pipeline.
|
// All faces are culled - can't be expressed in the pipeline.
|
||||||
return true;
|
return true;
|
||||||
|
@ -2027,11 +2027,11 @@ bool D3D12CommandProcessor::IssueDraw(xenos::PrimitiveType primitive_type,
|
||||||
scissor.height *= pixel_size_y;
|
scissor.height *= pixel_size_y;
|
||||||
|
|
||||||
// Update viewport, scissor, blend factor and stencil reference.
|
// 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.
|
// Update system constants before uploading them.
|
||||||
UpdateSystemConstantValues(
|
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,
|
indexed ? index_buffer_info->endianness : xenos::Endian::kNone,
|
||||||
viewport_info, pixel_size_x, pixel_size_y, used_texture_mask, early_z,
|
viewport_info, pixel_size_x, pixel_size_y, used_texture_mask, early_z,
|
||||||
GetCurrentColorMask(pixel_shader), pipeline_render_targets);
|
GetCurrentColorMask(pixel_shader), pipeline_render_targets);
|
||||||
|
@ -2785,7 +2785,7 @@ void D3D12CommandProcessor::ClearCommandAllocatorCache() {
|
||||||
|
|
||||||
void D3D12CommandProcessor::UpdateFixedFunctionState(
|
void D3D12CommandProcessor::UpdateFixedFunctionState(
|
||||||
const draw_util::ViewportInfo& viewport_info,
|
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
|
#if XE_UI_D3D12_FINE_GRAINED_DRAW_SCOPES
|
||||||
SCOPE_profile_cpu_f("gpu");
|
SCOPE_profile_cpu_f("gpu");
|
||||||
#endif // XE_UI_D3D12_FINE_GRAINED_DRAW_SCOPES
|
#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.
|
// choose the back face one only if drawing only back faces.
|
||||||
Register stencil_ref_mask_reg;
|
Register stencil_ref_mask_reg;
|
||||||
auto pa_su_sc_mode_cntl = regs.Get<reg::PA_SU_SC_MODE_CNTL>();
|
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 &&
|
regs.Get<reg::RB_DEPTHCONTROL>().backface_enable &&
|
||||||
pa_su_sc_mode_cntl.cull_front && !pa_su_sc_mode_cntl.cull_back) {
|
pa_su_sc_mode_cntl.cull_front && !pa_su_sc_mode_cntl.cull_back) {
|
||||||
stencil_ref_mask_reg = XE_GPU_REG_RB_STENCILREFMASK_BF;
|
stencil_ref_mask_reg = XE_GPU_REG_RB_STENCILREFMASK_BF;
|
||||||
|
@ -2870,7 +2870,7 @@ void D3D12CommandProcessor::UpdateFixedFunctionState(
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3D12CommandProcessor::UpdateSystemConstantValues(
|
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,
|
uint32_t line_loop_closing_index, xenos::Endian index_endian,
|
||||||
const draw_util::ViewportInfo& viewport_info, uint32_t pixel_size_x,
|
const draw_util::ViewportInfo& viewport_info, uint32_t pixel_size_x,
|
||||||
uint32_t pixel_size_y, uint32_t used_texture_mask, bool early_z,
|
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)
|
flags |= (pa_cl_clip_cntl.value & 0b111111)
|
||||||
<< DxbcShaderTranslator::kSysFlag_UserClipPlane0_Shift;
|
<< DxbcShaderTranslator::kSysFlag_UserClipPlane0_Shift;
|
||||||
}
|
}
|
||||||
// Whether SV_IsFrontFace matters.
|
// Whether the primitive is polygonal and SV_IsFrontFace matters.
|
||||||
if (primitive_two_faced) {
|
if (primitive_polygonal) {
|
||||||
flags |= DxbcShaderTranslator::kSysFlag_PrimitiveTwoFaced;
|
flags |= DxbcShaderTranslator::kSysFlag_PrimitivePolygonal;
|
||||||
}
|
}
|
||||||
// Primitive killing condition.
|
// Primitive killing condition.
|
||||||
if (pa_cl_clip_cntl.vtx_kill_or) {
|
if (pa_cl_clip_cntl.vtx_kill_or) {
|
||||||
|
@ -3082,7 +3082,7 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
|
||||||
// to do memexport.
|
// to do memexport.
|
||||||
if (sq_program_cntl.vs_export_mode ==
|
if (sq_program_cntl.vs_export_mode ==
|
||||||
xenos::VertexShaderExportMode::kMultipass ||
|
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)) {
|
pa_su_sc_mode_cntl.cull_back)) {
|
||||||
float nan_value = std::nanf("");
|
float nan_value = std::nanf("");
|
||||||
for (uint32_t i = 0; i < 3; ++i) {
|
for (uint32_t i = 0; i < 3; ++i) {
|
||||||
|
@ -3275,7 +3275,7 @@ void D3D12CommandProcessor::UpdateSystemConstantValues(
|
||||||
// are used.
|
// are used.
|
||||||
float poly_offset_front_scale = 0.0f, poly_offset_front_offset = 0.0f;
|
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;
|
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) {
|
if (pa_su_sc_mode_cntl.poly_offset_front_enable) {
|
||||||
poly_offset_front_scale =
|
poly_offset_front_scale =
|
||||||
regs[XE_GPU_REG_PA_SU_POLY_OFFSET_FRONT_SCALE].f32;
|
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;
|
||||||
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 !=
|
dirty |= system_constants_.edram_stencil_back_reference !=
|
||||||
rb_stencilrefmask_bf.stencilref;
|
rb_stencilrefmask_bf.stencilref;
|
||||||
system_constants_.edram_stencil_back_reference =
|
system_constants_.edram_stencil_back_reference =
|
||||||
|
|
|
@ -348,9 +348,9 @@ class D3D12CommandProcessor : public CommandProcessor {
|
||||||
|
|
||||||
void UpdateFixedFunctionState(const draw_util::ViewportInfo& viewport_info,
|
void UpdateFixedFunctionState(const draw_util::ViewportInfo& viewport_info,
|
||||||
const draw_util::Scissor& scissor,
|
const draw_util::Scissor& scissor,
|
||||||
bool primitive_two_faced);
|
bool primitive_polygonal);
|
||||||
void UpdateSystemConstantValues(
|
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,
|
uint32_t line_loop_closing_index, xenos::Endian index_endian,
|
||||||
const draw_util::ViewportInfo& viewport_info, uint32_t pixel_size_x,
|
const draw_util::ViewportInfo& viewport_info, uint32_t pixel_size_x,
|
||||||
uint32_t pixel_size_y, uint32_t used_texture_mask, bool early_z,
|
uint32_t pixel_size_y, uint32_t used_texture_mask, bool early_z,
|
||||||
|
|
|
@ -1285,7 +1285,7 @@ bool PipelineCache::GetCurrentStateDescription(
|
||||||
uint32_t(regs.Get<reg::VGT_HOS_CNTL>().tess_mode);
|
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,
|
host_vertex_shader_type != Shader::HostVertexShaderType::kVertex,
|
||||||
primitive_type);
|
primitive_type);
|
||||||
|
|
||||||
|
@ -1305,15 +1305,16 @@ bool PipelineCache::GetCurrentStateDescription(
|
||||||
// Here we also assume that only one side is culled - if two sides are culled,
|
// Here we also assume that only one side is culled - if two sides are culled,
|
||||||
// the D3D12 command processor will drop such draw early.
|
// the D3D12 command processor will drop such draw early.
|
||||||
bool cull_front, cull_back;
|
bool cull_front, cull_back;
|
||||||
if (primitive_two_faced) {
|
if (primitive_polygonal) {
|
||||||
cull_front = pa_su_sc_mode_cntl.cull_front != 0;
|
cull_front = pa_su_sc_mode_cntl.cull_front != 0;
|
||||||
cull_back = pa_su_sc_mode_cntl.cull_back != 0;
|
cull_back = pa_su_sc_mode_cntl.cull_back != 0;
|
||||||
} else {
|
} else {
|
||||||
|
// Non-polygonal primitives are never culled.
|
||||||
cull_front = false;
|
cull_front = false;
|
||||||
cull_back = false;
|
cull_back = false;
|
||||||
}
|
}
|
||||||
float poly_offset = 0.0f, poly_offset_scale = 0.0f;
|
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;
|
description_out.front_counter_clockwise = pa_su_sc_mode_cntl.face == 0;
|
||||||
if (cull_front) {
|
if (cull_front) {
|
||||||
description_out.cull_mode = PipelineCullMode::kFront;
|
description_out.cull_mode = PipelineCullMode::kFront;
|
||||||
|
@ -1327,8 +1328,8 @@ bool PipelineCache::GetCurrentStateDescription(
|
||||||
if (!cull_front) {
|
if (!cull_front) {
|
||||||
// Front faces aren't culled.
|
// Front faces aren't culled.
|
||||||
// Direct3D 12, unfortunately, doesn't support point fill mode.
|
// Direct3D 12, unfortunately, doesn't support point fill mode.
|
||||||
if (pa_su_sc_mode_cntl.polymode_front_ptype !=
|
if (primitive_polygonal && pa_su_sc_mode_cntl.polymode_front_ptype !=
|
||||||
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) {
|
if (!edram_rov_used_ && pa_su_sc_mode_cntl.poly_offset_front_enable) {
|
||||||
|
@ -1338,8 +1339,8 @@ bool PipelineCache::GetCurrentStateDescription(
|
||||||
}
|
}
|
||||||
if (!cull_back) {
|
if (!cull_back) {
|
||||||
// Back faces aren't culled.
|
// Back faces aren't culled.
|
||||||
if (pa_su_sc_mode_cntl.polymode_back_ptype !=
|
if (primitive_polygonal && pa_su_sc_mode_cntl.polymode_back_ptype !=
|
||||||
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
|
// Prefer front depth bias because in general, front faces are the ones
|
||||||
|
@ -1413,7 +1414,7 @@ bool PipelineCache::GetCurrentStateDescription(
|
||||||
if (rb_depthcontrol.stencil_enable) {
|
if (rb_depthcontrol.stencil_enable) {
|
||||||
description_out.stencil_enable = 1;
|
description_out.stencil_enable = 1;
|
||||||
bool stencil_backface_enable =
|
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
|
// Per-face masks not supported by Direct3D 12, choose the back face
|
||||||
// ones only if drawing only back faces.
|
// ones only if drawing only back faces.
|
||||||
Register stencil_ref_mask_reg;
|
Register stencil_ref_mask_reg;
|
||||||
|
|
|
@ -770,7 +770,7 @@ void DxbcShaderTranslator::StartPixelShader() {
|
||||||
uint32_t(CbufferRegister::kSystemConstants),
|
uint32_t(CbufferRegister::kSystemConstants),
|
||||||
kSysConst_Flags_Vec)
|
kSysConst_Flags_Vec)
|
||||||
.Select(kSysConst_Flags_Comp),
|
.Select(kSysConst_Flags_Comp),
|
||||||
DxbcSrc::LU(kSysFlag_PrimitiveTwoFaced));
|
DxbcSrc::LU(kSysFlag_PrimitivePolygonal));
|
||||||
DxbcOpIf(true, DxbcSrc::R(param_gen_temp, DxbcSrc::kZZZZ));
|
DxbcOpIf(true, DxbcSrc::R(param_gen_temp, DxbcSrc::kZZZZ));
|
||||||
{
|
{
|
||||||
// Negate modifier flips the sign bit even for 0 - set it to minus for
|
// Negate modifier flips the sign bit even for 0 - set it to minus for
|
||||||
|
|
|
@ -124,7 +124,7 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
kSysFlag_UserClipPlane4_Shift,
|
kSysFlag_UserClipPlane4_Shift,
|
||||||
kSysFlag_UserClipPlane5_Shift,
|
kSysFlag_UserClipPlane5_Shift,
|
||||||
kSysFlag_KillIfAnyVertexKilled_Shift,
|
kSysFlag_KillIfAnyVertexKilled_Shift,
|
||||||
kSysFlag_PrimitiveTwoFaced_Shift,
|
kSysFlag_PrimitivePolygonal_Shift,
|
||||||
kSysFlag_AlphaPassIfLess_Shift,
|
kSysFlag_AlphaPassIfLess_Shift,
|
||||||
kSysFlag_AlphaPassIfEqual_Shift,
|
kSysFlag_AlphaPassIfEqual_Shift,
|
||||||
kSysFlag_AlphaPassIfGreater_Shift,
|
kSysFlag_AlphaPassIfGreater_Shift,
|
||||||
|
@ -165,7 +165,7 @@ class DxbcShaderTranslator : public ShaderTranslator {
|
||||||
kSysFlag_UserClipPlane4 = 1u << kSysFlag_UserClipPlane4_Shift,
|
kSysFlag_UserClipPlane4 = 1u << kSysFlag_UserClipPlane4_Shift,
|
||||||
kSysFlag_UserClipPlane5 = 1u << kSysFlag_UserClipPlane5_Shift,
|
kSysFlag_UserClipPlane5 = 1u << kSysFlag_UserClipPlane5_Shift,
|
||||||
kSysFlag_KillIfAnyVertexKilled = 1u << kSysFlag_KillIfAnyVertexKilled_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_AlphaPassIfLess = 1u << kSysFlag_AlphaPassIfLess_Shift,
|
||||||
kSysFlag_AlphaPassIfEqual = 1u << kSysFlag_AlphaPassIfEqual_Shift,
|
kSysFlag_AlphaPassIfEqual = 1u << kSysFlag_AlphaPassIfEqual_Shift,
|
||||||
kSysFlag_AlphaPassIfGreater = 1u << kSysFlag_AlphaPassIfGreater_Shift,
|
kSysFlag_AlphaPassIfGreater = 1u << kSysFlag_AlphaPassIfGreater_Shift,
|
||||||
|
|
|
@ -64,7 +64,15 @@ enum class PrimitiveType : uint32_t {
|
||||||
kQuadPatch = 0x12,
|
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 ||
|
if (tessellated && (type == PrimitiveType::kTrianglePatch ||
|
||||||
type == PrimitiveType::kQuadPatch)) {
|
type == PrimitiveType::kQuadPatch)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -74,6 +82,7 @@ inline bool IsPrimitiveTwoFaced(bool tessellated, PrimitiveType type) {
|
||||||
case PrimitiveType::kTriangleFan:
|
case PrimitiveType::kTriangleFan:
|
||||||
case PrimitiveType::kTriangleStrip:
|
case PrimitiveType::kTriangleStrip:
|
||||||
case PrimitiveType::kTriangleWithWFlags:
|
case PrimitiveType::kTriangleWithWFlags:
|
||||||
|
case PrimitiveType::kRectangleList:
|
||||||
case PrimitiveType::kQuadList:
|
case PrimitiveType::kQuadList:
|
||||||
case PrimitiveType::kQuadStrip:
|
case PrimitiveType::kQuadStrip:
|
||||||
case PrimitiveType::kPolygon:
|
case PrimitiveType::kPolygon:
|
||||||
|
|
Loading…
Reference in New Issue