mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 22:06:59 +01:00
gpu: honour DB_ALPHA_TO_MASK as alpha-to-coverage and keep its depth writes behind the shader
This commit is contained in:
@@ -73,7 +73,6 @@ constexpr auto MakeContextDispatchTable() {
|
|||||||
g_hw_ctx_func[Pm4::PA_SC_BINNER_CNTL_0] = HwCtxSetPaScExtendedControl;
|
g_hw_ctx_func[Pm4::PA_SC_BINNER_CNTL_0] = HwCtxSetPaScExtendedControl;
|
||||||
g_hw_ctx_func[Pm4::PA_SC_BINNER_CNTL_1] = HwCtxSetPaScExtendedControl;
|
g_hw_ctx_func[Pm4::PA_SC_BINNER_CNTL_1] = HwCtxSetPaScExtendedControl;
|
||||||
g_hw_ctx_func[Pm4::PA_SC_CONSERVATIVE_RASTERIZATION_CNTL] = HwCtxSetPaScExtendedControl;
|
g_hw_ctx_func[Pm4::PA_SC_CONSERVATIVE_RASTERIZATION_CNTL] = HwCtxSetPaScExtendedControl;
|
||||||
g_hw_ctx_func[Pm4::DB_ALPHA_TO_MASK] = HwCtxSetAlphaToMask;
|
|
||||||
g_hw_ctx_func[Pm4::VGT_DRAW_PAYLOAD_CNTL] = HwCtxSetDrawPayloadControl;
|
g_hw_ctx_func[Pm4::VGT_DRAW_PAYLOAD_CNTL] = HwCtxSetDrawPayloadControl;
|
||||||
g_hw_ctx_func[Pm4::VGT_PRIMITIVEID_RESET] = HwCtxSetPrimitiveIdReset;
|
g_hw_ctx_func[Pm4::VGT_PRIMITIVEID_RESET] = HwCtxSetPrimitiveIdReset;
|
||||||
g_hw_ctx_func[Pm4::PA_CL_OBJPRIM_ID_CNTL] = HwCtxSetObjprimIdControl;
|
g_hw_ctx_func[Pm4::PA_CL_OBJPRIM_ID_CNTL] = HwCtxSetObjprimIdControl;
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ uint32_t HwCtxSetAaMask(CommandProcessor&, uint32_t, uint32_t, const uint32_t*,
|
|||||||
uint32_t HwCtxSetVtxControl(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
|
uint32_t HwCtxSetVtxControl(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
|
||||||
uint32_t HwCtxSetPaScExtendedControl(CommandProcessor&, uint32_t, uint32_t, const uint32_t*,
|
uint32_t HwCtxSetPaScExtendedControl(CommandProcessor&, uint32_t, uint32_t, const uint32_t*,
|
||||||
uint32_t);
|
uint32_t);
|
||||||
uint32_t HwCtxSetAlphaToMask(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
|
|
||||||
uint32_t HwCtxSetDrawPayloadControl(CommandProcessor&, uint32_t, uint32_t, const uint32_t*,
|
uint32_t HwCtxSetDrawPayloadControl(CommandProcessor&, uint32_t, uint32_t, const uint32_t*,
|
||||||
uint32_t);
|
uint32_t);
|
||||||
uint32_t HwCtxSetPrimitiveIdReset(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
|
uint32_t HwCtxSetPrimitiveIdReset(CommandProcessor&, uint32_t, uint32_t, const uint32_t*, uint32_t);
|
||||||
|
|||||||
@@ -283,8 +283,6 @@ KYTY_HW_CTX_PARSER(HwCtxSetCentroidPriority) {
|
|||||||
static void HwCtxIgnoreAaMaskRegister([[maybe_unused]] uint32_t cmd_offset,
|
static void HwCtxIgnoreAaMaskRegister([[maybe_unused]] uint32_t cmd_offset,
|
||||||
[[maybe_unused]] uint32_t value) {}
|
[[maybe_unused]] uint32_t value) {}
|
||||||
|
|
||||||
static void HwCtxIgnoreAlphaToMaskRegister([[maybe_unused]] uint32_t value) {}
|
|
||||||
|
|
||||||
static void HwCtxIgnorePrimitiveIdReset([[maybe_unused]] uint32_t value) {}
|
static void HwCtxIgnorePrimitiveIdReset([[maybe_unused]] uint32_t value) {}
|
||||||
|
|
||||||
static void HwCtxIgnoreVtxControl([[maybe_unused]] uint32_t value) {}
|
static void HwCtxIgnoreVtxControl([[maybe_unused]] uint32_t value) {}
|
||||||
@@ -429,16 +427,6 @@ KYTY_HW_CTX_PARSER(HwCtxSetPointState) {
|
|||||||
return num_values;
|
return num_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
KYTY_HW_CTX_PARSER(HwCtxSetAlphaToMask) {
|
|
||||||
auto num_values = KYTY_PM4_LEN(cmd_id) - 2u;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < num_values; i++) {
|
|
||||||
HwCtxIgnoreAlphaToMaskRegister(buffer[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return num_values;
|
|
||||||
}
|
|
||||||
|
|
||||||
KYTY_HW_CTX_PARSER(HwCtxSetDrawPayloadControl) {
|
KYTY_HW_CTX_PARSER(HwCtxSetDrawPayloadControl) {
|
||||||
cp.GetCtx().SetDrawPayloadControl(buffer[0]);
|
cp.GetCtx().SetDrawPayloadControl(buffer[0]);
|
||||||
return KYTY_PM4_LEN(cmd_id) - 2u;
|
return KYTY_PM4_LEN(cmd_id) - 2u;
|
||||||
@@ -3465,7 +3453,8 @@ void GraphicsInitJmpTablesCxIndirect() {
|
|||||||
g_hw_ctx_indirect_func[Pm4::PA_SC_CONSERVATIVE_RASTERIZATION_CNTL] =
|
g_hw_ctx_indirect_func[Pm4::PA_SC_CONSERVATIVE_RASTERIZATION_CNTL] =
|
||||||
[](KYTY_HW_CTX_INDIRECT_ARGS) { HwCtxIgnorePaScExtendedControl(cmd_offset, value); };
|
[](KYTY_HW_CTX_INDIRECT_ARGS) { HwCtxIgnorePaScExtendedControl(cmd_offset, value); };
|
||||||
g_hw_ctx_indirect_func[Pm4::DB_ALPHA_TO_MASK] = [](KYTY_HW_CTX_INDIRECT_ARGS) {
|
g_hw_ctx_indirect_func[Pm4::DB_ALPHA_TO_MASK] = [](KYTY_HW_CTX_INDIRECT_ARGS) {
|
||||||
HwCtxIgnoreAlphaToMaskRegister(value);
|
cp.GetCtx().SetAlphaToMaskEnable(
|
||||||
|
KYTY_PM4_GET(value, DB_ALPHA_TO_MASK, ALPHA_TO_MASK_ENABLE) != 0);
|
||||||
};
|
};
|
||||||
g_hw_ctx_indirect_func[Pm4::CB_COLOR_CONTROL] = [](KYTY_HW_CTX_INDIRECT_ARGS) {
|
g_hw_ctx_indirect_func[Pm4::CB_COLOR_CONTROL] = [](KYTY_HW_CTX_INDIRECT_ARGS) {
|
||||||
cp.GetCtx().SetColorControl(DecodeColorControl(value));
|
cp.GetCtx().SetColorControl(DecodeColorControl(value));
|
||||||
|
|||||||
@@ -576,6 +576,12 @@ struct ShaderRegisters {
|
|||||||
uint32_t m_paScShaderControl = 0;
|
uint32_t m_paScShaderControl = 0;
|
||||||
|
|
||||||
DepthShaderControl db_shader_control;
|
DepthShaderControl db_shader_control;
|
||||||
|
bool alpha_to_mask_enable = false;
|
||||||
|
|
||||||
|
// DB_SHADER_CONTROL.ALPHA_TO_MASK_DISABLE overrides DB_ALPHA_TO_MASK per shader.
|
||||||
|
[[nodiscard]] bool AlphaToMask() const {
|
||||||
|
return alpha_to_mask_enable && !db_shader_control.alpha_to_mask_disable;
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] uint32_t GetExportCount() const {
|
[[nodiscard]] uint32_t GetExportCount() const {
|
||||||
return 1u + ((m_spiVsOutConfig >> 1u) & 0x1Fu);
|
return 1u + ((m_spiVsOutConfig >> 1u) & 0x1Fu);
|
||||||
@@ -915,6 +921,7 @@ public:
|
|||||||
void SetDepthShaderControl(const DepthShaderControl& value) {
|
void SetDepthShaderControl(const DepthShaderControl& value) {
|
||||||
m_sh_regs.db_shader_control = value;
|
m_sh_regs.db_shader_control = value;
|
||||||
}
|
}
|
||||||
|
void SetAlphaToMaskEnable(bool value) { m_sh_regs.alpha_to_mask_enable = value; }
|
||||||
|
|
||||||
void SetScShaderControl(uint32_t value) { m_sh_regs.m_paScShaderControl = value; }
|
void SetScShaderControl(uint32_t value) { m_sh_regs.m_paScShaderControl = value; }
|
||||||
|
|
||||||
|
|||||||
@@ -549,6 +549,8 @@ constexpr uint32_t VGT_SHADER_STAGES_EN = 0x2D5;
|
|||||||
constexpr uint32_t VGT_LS_HS_CONFIG = 0x2D6;
|
constexpr uint32_t VGT_LS_HS_CONFIG = 0x2D6;
|
||||||
constexpr uint32_t VGT_TF_PARAM = 0x2DB;
|
constexpr uint32_t VGT_TF_PARAM = 0x2DB;
|
||||||
constexpr uint32_t DB_ALPHA_TO_MASK = 0x2DC;
|
constexpr uint32_t DB_ALPHA_TO_MASK = 0x2DC;
|
||||||
|
constexpr uint32_t DB_ALPHA_TO_MASK_ALPHA_TO_MASK_ENABLE_SHIFT = 0;
|
||||||
|
constexpr uint32_t DB_ALPHA_TO_MASK_ALPHA_TO_MASK_ENABLE_MASK = 0x1;
|
||||||
constexpr uint32_t PA_SU_POLY_OFFSET_DB_FMT_CNTL = 0x2DE;
|
constexpr uint32_t PA_SU_POLY_OFFSET_DB_FMT_CNTL = 0x2DE;
|
||||||
constexpr uint32_t PA_SU_POLY_OFFSET_DB_FMT_CNTL_NEG_NUM_DB_BITS_SHIFT = 0;
|
constexpr uint32_t PA_SU_POLY_OFFSET_DB_FMT_CNTL_NEG_NUM_DB_BITS_SHIFT = 0;
|
||||||
constexpr uint32_t PA_SU_POLY_OFFSET_DB_FMT_CNTL_NEG_NUM_DB_BITS_MASK = 0xFF;
|
constexpr uint32_t PA_SU_POLY_OFFSET_DB_FMT_CNTL_NEG_NUM_DB_BITS_MASK = 0xFF;
|
||||||
|
|||||||
@@ -971,6 +971,7 @@ PipelineCache::Pipeline& PipelineCache::GetGraphicsPipeline(
|
|||||||
if (static_params.sample_shading_enable && !m_graphics.sample_rate_shading_enabled) {
|
if (static_params.sample_shading_enable && !m_graphics.sample_rate_shading_enabled) {
|
||||||
EXIT("Pipeline: sample-rate shading is required but unsupported by the host\n");
|
EXIT("Pipeline: sample-rate shading is required but unsupported by the host\n");
|
||||||
}
|
}
|
||||||
|
static_params.alpha_to_coverage_enable = ps_active && ctx.GetShaderRegisters().AlphaToMask();
|
||||||
const bool rect_list = Prospero::IsRectList(command.GetUserConfig().GetPrimType());
|
const bool rect_list = Prospero::IsRectList(command.GetUserConfig().GetPrimType());
|
||||||
static_params.cull_back = !rect_list && mc.cull_back;
|
static_params.cull_back = !rect_list && mc.cull_back;
|
||||||
static_params.cull_front = !rect_list && mc.cull_front;
|
static_params.cull_front = !rect_list && mc.cull_front;
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ struct PipelineStaticParameters {
|
|||||||
bool primitive_restart_enable = false;
|
bool primitive_restart_enable = false;
|
||||||
uint32_t samples = 1;
|
uint32_t samples = 1;
|
||||||
bool sample_shading_enable = false;
|
bool sample_shading_enable = false;
|
||||||
|
bool alpha_to_coverage_enable = false;
|
||||||
uint32_t color_mask[RENDER_COLOR_ATTACHMENTS_MAX] = {};
|
uint32_t color_mask[RENDER_COLOR_ATTACHMENTS_MAX] = {};
|
||||||
bool cull_front = false;
|
bool cull_front = false;
|
||||||
bool cull_back = false;
|
bool cull_back = false;
|
||||||
@@ -62,7 +63,7 @@ struct PipelineStaticParameters {
|
|||||||
static_assert(std::is_trivially_copyable_v<PipelineStaticParameters>);
|
static_assert(std::is_trivially_copyable_v<PipelineStaticParameters>);
|
||||||
static_assert(std::is_standard_layout_v<PipelineStaticParameters>);
|
static_assert(std::is_standard_layout_v<PipelineStaticParameters>);
|
||||||
static_assert(alignof(PipelineStaticParameters) == 1);
|
static_assert(alignof(PipelineStaticParameters) == 1);
|
||||||
static_assert(sizeof(PipelineStaticParameters) == 116);
|
static_assert(sizeof(PipelineStaticParameters) == 117);
|
||||||
|
|
||||||
struct PipelineRenderingState {
|
struct PipelineRenderingState {
|
||||||
std::array<vk::Format, RENDER_COLOR_ATTACHMENTS_MAX> color_formats {};
|
std::array<vk::Format, RENDER_COLOR_ATTACHMENTS_MAX> color_formats {};
|
||||||
|
|||||||
@@ -422,6 +422,8 @@ void CreatePipelineInternal(GraphicContext& graphics, PipelineCache::Pipeline& p
|
|||||||
multisampling.sampleShadingEnable = static_params.sample_shading_enable ? VK_TRUE : VK_FALSE;
|
multisampling.sampleShadingEnable = static_params.sample_shading_enable ? VK_TRUE : VK_FALSE;
|
||||||
multisampling.rasterizationSamples = vulkan_sample_count(static_params.samples);
|
multisampling.rasterizationSamples = vulkan_sample_count(static_params.samples);
|
||||||
multisampling.minSampleShading = 1.0f;
|
multisampling.minSampleShading = 1.0f;
|
||||||
|
multisampling.alphaToCoverageEnable =
|
||||||
|
static_params.alpha_to_coverage_enable ? VK_TRUE : VK_FALSE;
|
||||||
|
|
||||||
vk::PipelineColorBlendAttachmentState color_blend_attachment[RENDER_COLOR_ATTACHMENTS_MAX] = {};
|
vk::PipelineColorBlendAttachmentState color_blend_attachment[RENDER_COLOR_ATTACHMENTS_MAX] = {};
|
||||||
for (uint32_t i = 0; i < rendering.color_count; i++) {
|
for (uint32_t i = 0; i < rendering.color_count; i++) {
|
||||||
|
|||||||
@@ -436,7 +436,7 @@ static bool DrawHasValidVertexShader(const HW::Shader& sh_ctx) {
|
|||||||
static bool PixelShaderHasDepthOrCoverageSideEffects(const HW::ShaderRegisters& sh_regs) {
|
static bool PixelShaderHasDepthOrCoverageSideEffects(const HW::ShaderRegisters& sh_regs) {
|
||||||
const auto& db = sh_regs.db_shader_control;
|
const auto& db = sh_regs.db_shader_control;
|
||||||
return db.shader_kill_enable || db.shader_z_export_enable || db.shader_mask_export_enable ||
|
return db.shader_kill_enable || db.shader_z_export_enable || db.shader_mask_export_enable ||
|
||||||
db.shader_dual_export_enable || db.shader_execute_on_noop;
|
db.shader_dual_export_enable || db.shader_execute_on_noop || sh_regs.AlphaToMask();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DrawRenderState {
|
struct DrawRenderState {
|
||||||
|
|||||||
@@ -355,10 +355,11 @@ static void ShaderGetStaticInputInfoPS(
|
|||||||
ps_info.ps_pixel_kill_enable = sh.db_shader_control.shader_kill_enable;
|
ps_info.ps_pixel_kill_enable = sh.db_shader_control.shader_kill_enable;
|
||||||
ps_info.ps_depth_export_enable = sh.db_shader_control.shader_z_export_enable;
|
ps_info.ps_depth_export_enable = sh.db_shader_control.shader_z_export_enable;
|
||||||
ps_info.ps_sample_mask_export_enable = sh.db_shader_control.shader_mask_export_enable;
|
ps_info.ps_sample_mask_export_enable = sh.db_shader_control.shader_mask_export_enable;
|
||||||
|
// Alpha-to-mask coverage must gate depth writes, so it rules out early fragment tests.
|
||||||
ps_info.ps_early_z =
|
ps_info.ps_early_z =
|
||||||
(sh.db_shader_control.shader_z_behavior == 1 && !sh.db_shader_control.shader_kill_enable &&
|
(sh.db_shader_control.shader_z_behavior == 1 && !sh.db_shader_control.shader_kill_enable &&
|
||||||
!sh.db_shader_control.shader_z_export_enable &&
|
!sh.db_shader_control.shader_z_export_enable &&
|
||||||
!sh.db_shader_control.shader_mask_export_enable);
|
!sh.db_shader_control.shader_mask_export_enable && !sh.AlphaToMask());
|
||||||
ps_info.ps_execute_on_noop = sh.db_shader_control.shader_execute_on_noop;
|
ps_info.ps_execute_on_noop = sh.db_shader_control.shader_execute_on_noop;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < ps_info.input_num; i++) {
|
for (uint32_t i = 0; i < ps_info.input_num; i++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user