radv: add support for dynamic blend equation
Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20281>
This commit is contained in:

committed by
Marge Bot

parent
11382a6711
commit
daa2aeaa0c
@@ -245,6 +245,25 @@ radv_bind_dynamic_state(struct radv_cmd_buffer *cmd_buffer, const struct radv_dy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (copy_mask & RADV_DYNAMIC_COLOR_BLEND_EQUATION) {
|
||||||
|
for (uint32_t i = 0; i < MAX_RTS; i++) {
|
||||||
|
if (dest->vk.cb.attachments[i].src_color_blend_factor != src->vk.cb.attachments[i].src_color_blend_factor ||
|
||||||
|
dest->vk.cb.attachments[i].dst_color_blend_factor != src->vk.cb.attachments[i].dst_color_blend_factor ||
|
||||||
|
dest->vk.cb.attachments[i].color_blend_op != src->vk.cb.attachments[i].color_blend_op ||
|
||||||
|
dest->vk.cb.attachments[i].src_alpha_blend_factor != src->vk.cb.attachments[i].src_alpha_blend_factor ||
|
||||||
|
dest->vk.cb.attachments[i].dst_alpha_blend_factor != src->vk.cb.attachments[i].dst_alpha_blend_factor ||
|
||||||
|
dest->vk.cb.attachments[i].alpha_blend_op != src->vk.cb.attachments[i].alpha_blend_op) {
|
||||||
|
dest->vk.cb.attachments[i].src_color_blend_factor = src->vk.cb.attachments[i].src_color_blend_factor;
|
||||||
|
dest->vk.cb.attachments[i].dst_color_blend_factor = src->vk.cb.attachments[i].dst_color_blend_factor;
|
||||||
|
dest->vk.cb.attachments[i].color_blend_op = src->vk.cb.attachments[i].color_blend_op;
|
||||||
|
dest->vk.cb.attachments[i].src_alpha_blend_factor = src->vk.cb.attachments[i].src_alpha_blend_factor;
|
||||||
|
dest->vk.cb.attachments[i].dst_alpha_blend_factor = src->vk.cb.attachments[i].dst_alpha_blend_factor;
|
||||||
|
dest->vk.cb.attachments[i].alpha_blend_op = src->vk.cb.attachments[i].alpha_blend_op;
|
||||||
|
dest_mask |= RADV_DYNAMIC_COLOR_BLEND_EQUATION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define RADV_CMP_COPY(field, flag) \
|
#define RADV_CMP_COPY(field, flag) \
|
||||||
if (copy_mask & flag) { \
|
if (copy_mask & flag) { \
|
||||||
if (dest->field != src->field) { \
|
if (dest->field != src->field) { \
|
||||||
@@ -1939,17 +1958,10 @@ radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer)
|
|||||||
if (radv_rast_prim_is_points_or_lines(cmd_buffer->state.emitted_graphics_pipeline->rast_prim) != radv_rast_prim_is_points_or_lines(pipeline->rast_prim))
|
if (radv_rast_prim_is_points_or_lines(cmd_buffer->state.emitted_graphics_pipeline->rast_prim) != radv_rast_prim_is_points_or_lines(pipeline->rast_prim))
|
||||||
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_GUARDBAND;
|
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_GUARDBAND;
|
||||||
|
|
||||||
if (cmd_buffer->state.emitted_graphics_pipeline->mrt0_is_dual_src != pipeline->mrt0_is_dual_src ||
|
if (cmd_buffer->state.emitted_graphics_pipeline->custom_blend_mode != pipeline->custom_blend_mode)
|
||||||
cmd_buffer->state.emitted_graphics_pipeline->custom_blend_mode != pipeline->custom_blend_mode)
|
|
||||||
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_LOGIC_OP |
|
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_LOGIC_OP |
|
||||||
RADV_CMD_DIRTY_DYNAMIC_LOGIC_OP_ENABLE;
|
RADV_CMD_DIRTY_DYNAMIC_LOGIC_OP_ENABLE;
|
||||||
|
|
||||||
if (memcmp(cmd_buffer->state.emitted_graphics_pipeline->cb_blend_control,
|
|
||||||
pipeline->cb_blend_control, sizeof(pipeline->cb_blend_control)) ||
|
|
||||||
memcmp(cmd_buffer->state.emitted_graphics_pipeline->sx_mrt_blend_opt,
|
|
||||||
pipeline->sx_mrt_blend_opt, sizeof(pipeline->sx_mrt_blend_opt)))
|
|
||||||
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_ENABLE;
|
|
||||||
|
|
||||||
if (cmd_buffer->state.emitted_graphics_pipeline->ms.sample_shading_enable != pipeline->ms.sample_shading_enable ||
|
if (cmd_buffer->state.emitted_graphics_pipeline->ms.sample_shading_enable != pipeline->ms.sample_shading_enable ||
|
||||||
cmd_buffer->state.emitted_graphics_pipeline->ms.min_sample_shading != pipeline->ms.min_sample_shading ||
|
cmd_buffer->state.emitted_graphics_pipeline->ms.min_sample_shading != pipeline->ms.min_sample_shading ||
|
||||||
cmd_buffer->state.emitted_graphics_pipeline->pa_sc_mode_cntl_1 != pipeline->pa_sc_mode_cntl_1 ||
|
cmd_buffer->state.emitted_graphics_pipeline->pa_sc_mode_cntl_1 != pipeline->pa_sc_mode_cntl_1 ||
|
||||||
@@ -2401,6 +2413,26 @@ radv_emit_clipping(struct radv_cmd_buffer *cmd_buffer)
|
|||||||
S_028810_DX_LINEAR_ATTR_CLIP_ENA(1));
|
S_028810_DX_LINEAR_ATTR_CLIP_ENA(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
radv_is_mrt0_dual_src(struct radv_cmd_buffer *cmd_buffer)
|
||||||
|
{
|
||||||
|
const struct radv_dynamic_state *d = &cmd_buffer->state.dynamic;
|
||||||
|
|
||||||
|
if (!d->vk.cb.attachments[0].write_mask || !d->vk.cb.attachments[0].blend_enable)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const struct vk_color_blend_attachment_state att = {
|
||||||
|
.color_blend_op = d->vk.cb.attachments[0].color_blend_op,
|
||||||
|
.src_color_blend_factor = d->vk.cb.attachments[0].src_color_blend_factor,
|
||||||
|
.dst_color_blend_factor = d->vk.cb.attachments[0].dst_color_blend_factor,
|
||||||
|
.alpha_blend_op = d->vk.cb.attachments[0].alpha_blend_op,
|
||||||
|
.src_alpha_blend_factor = d->vk.cb.attachments[0].src_alpha_blend_factor,
|
||||||
|
.dst_alpha_blend_factor = d->vk.cb.attachments[0].dst_alpha_blend_factor,
|
||||||
|
};
|
||||||
|
|
||||||
|
return radv_can_enable_dual_src(&att);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
radv_emit_logic_op(struct radv_cmd_buffer *cmd_buffer)
|
radv_emit_logic_op(struct radv_cmd_buffer *cmd_buffer)
|
||||||
{
|
{
|
||||||
@@ -2416,8 +2448,10 @@ radv_emit_logic_op(struct radv_cmd_buffer *cmd_buffer)
|
|||||||
|
|
||||||
if (cmd_buffer->device->physical_device->rad_info.has_rbplus) {
|
if (cmd_buffer->device->physical_device->rad_info.has_rbplus) {
|
||||||
/* RB+ doesn't work with dual source blending, logic op and CB_RESOLVE. */
|
/* RB+ doesn't work with dual source blending, logic op and CB_RESOLVE. */
|
||||||
|
bool mrt0_is_dual_src = radv_is_mrt0_dual_src(cmd_buffer);
|
||||||
|
|
||||||
cb_color_control |=
|
cb_color_control |=
|
||||||
S_028808_DISABLE_DUAL_QUAD(pipeline->mrt0_is_dual_src || d->vk.cb.logic_op_enable ||
|
S_028808_DISABLE_DUAL_QUAD(mrt0_is_dual_src || d->vk.cb.logic_op_enable ||
|
||||||
pipeline->custom_blend_mode == V_028808_CB_RESOLVE);
|
pipeline->custom_blend_mode == V_028808_CB_RESOLVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4056,29 +4090,98 @@ radv_emit_sample_mask(struct radv_cmd_buffer *cmd_buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
radv_emit_color_blend_enable(struct radv_cmd_buffer *cmd_buffer)
|
radv_emit_color_blend(struct radv_cmd_buffer *cmd_buffer)
|
||||||
{
|
{
|
||||||
const struct radv_physical_device *pdevice = cmd_buffer->device->physical_device;
|
const struct radv_physical_device *pdevice = cmd_buffer->device->physical_device;
|
||||||
const struct radv_graphics_pipeline *pipeline = cmd_buffer->state.graphics_pipeline;
|
const enum amd_gfx_level gfx_level = pdevice->rad_info.gfx_level;
|
||||||
const struct radv_dynamic_state *d = &cmd_buffer->state.dynamic;
|
const struct radv_dynamic_state *d = &cmd_buffer->state.dynamic;
|
||||||
unsigned cb_blend_control[MAX_RTS], sx_mrt_blend_opt[MAX_RTS];
|
unsigned cb_blend_control[MAX_RTS], sx_mrt_blend_opt[MAX_RTS];
|
||||||
|
bool mrt0_is_dual_src = radv_is_mrt0_dual_src(cmd_buffer);
|
||||||
|
|
||||||
for (unsigned i = 0; i < MAX_RTS; i++) {
|
for (unsigned i = 0; i < MAX_RTS; i++) {
|
||||||
bool blend_enable = d->vk.cb.attachments[i].blend_enable;
|
VkBlendOp eqRGB = d->vk.cb.attachments[i].color_blend_op;
|
||||||
|
VkBlendFactor srcRGB = d->vk.cb.attachments[i].src_color_blend_factor;
|
||||||
|
VkBlendFactor dstRGB = d->vk.cb.attachments[i].dst_color_blend_factor;
|
||||||
|
VkBlendOp eqA = d->vk.cb.attachments[i].alpha_blend_op;
|
||||||
|
VkBlendFactor srcA = d->vk.cb.attachments[i].src_alpha_blend_factor;
|
||||||
|
VkBlendFactor dstA = d->vk.cb.attachments[i].dst_alpha_blend_factor;
|
||||||
|
unsigned srcRGB_opt, dstRGB_opt, srcA_opt, dstA_opt;
|
||||||
|
unsigned blend_cntl = 0;
|
||||||
|
|
||||||
cb_blend_control[i] = pipeline->cb_blend_control[i];
|
cb_blend_control[i] = sx_mrt_blend_opt[i] = 0;
|
||||||
sx_mrt_blend_opt[i] = pipeline->sx_mrt_blend_opt[i];
|
|
||||||
|
|
||||||
if (blend_enable) {
|
/* Ignore other blend targets if dual-source blending is enabled to prevent wrong behaviour.
|
||||||
cb_blend_control[i] |= S_028780_ENABLE(1);
|
*/
|
||||||
} else if (pdevice->rad_info.has_rbplus) {
|
if (i > 0 && mrt0_is_dual_src)
|
||||||
/* Make sure to keep RB+ blend optimizations disabled for dual source blending. */
|
continue;
|
||||||
if (G_028760_COLOR_COMB_FCN(sx_mrt_blend_opt[i]) != V_028760_OPT_COMB_NONE &&
|
|
||||||
G_028760_ALPHA_COMB_FCN(sx_mrt_blend_opt[i]) != V_028760_OPT_COMB_NONE) {
|
if (!d->vk.cb.attachments[i].blend_enable) {
|
||||||
sx_mrt_blend_opt[i] &= C_028760_COLOR_COMB_FCN;
|
|
||||||
sx_mrt_blend_opt[i] &= C_028760_ALPHA_COMB_FCN;
|
|
||||||
sx_mrt_blend_opt[i] |= S_028760_COLOR_COMB_FCN(V_028760_OPT_COMB_BLEND_DISABLED) |
|
sx_mrt_blend_opt[i] |= S_028760_COLOR_COMB_FCN(V_028760_OPT_COMB_BLEND_DISABLED) |
|
||||||
S_028760_ALPHA_COMB_FCN(V_028760_OPT_COMB_BLEND_DISABLED);
|
S_028760_ALPHA_COMB_FCN(V_028760_OPT_COMB_BLEND_DISABLED);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
radv_normalize_blend_factor(eqRGB, &srcRGB, &dstRGB);
|
||||||
|
radv_normalize_blend_factor(eqA, &srcA, &dstA);
|
||||||
|
|
||||||
|
/* Blending optimizations for RB+.
|
||||||
|
* These transformations don't change the behavior.
|
||||||
|
*
|
||||||
|
* First, get rid of DST in the blend factors:
|
||||||
|
* func(src * DST, dst * 0) ---> func(src * 0, dst * SRC)
|
||||||
|
*/
|
||||||
|
si_blend_remove_dst(&eqRGB, &srcRGB, &dstRGB, VK_BLEND_FACTOR_DST_COLOR,
|
||||||
|
VK_BLEND_FACTOR_SRC_COLOR);
|
||||||
|
|
||||||
|
si_blend_remove_dst(&eqA, &srcA, &dstA, VK_BLEND_FACTOR_DST_COLOR,
|
||||||
|
VK_BLEND_FACTOR_SRC_COLOR);
|
||||||
|
|
||||||
|
si_blend_remove_dst(&eqA, &srcA, &dstA, VK_BLEND_FACTOR_DST_ALPHA,
|
||||||
|
VK_BLEND_FACTOR_SRC_ALPHA);
|
||||||
|
|
||||||
|
/* Look up the ideal settings from tables. */
|
||||||
|
srcRGB_opt = si_translate_blend_opt_factor(srcRGB, false);
|
||||||
|
dstRGB_opt = si_translate_blend_opt_factor(dstRGB, false);
|
||||||
|
srcA_opt = si_translate_blend_opt_factor(srcA, true);
|
||||||
|
dstA_opt = si_translate_blend_opt_factor(dstA, true);
|
||||||
|
|
||||||
|
/* Handle interdependencies. */
|
||||||
|
if (si_blend_factor_uses_dst(srcRGB))
|
||||||
|
dstRGB_opt = V_028760_BLEND_OPT_PRESERVE_NONE_IGNORE_NONE;
|
||||||
|
if (si_blend_factor_uses_dst(srcA))
|
||||||
|
dstA_opt = V_028760_BLEND_OPT_PRESERVE_NONE_IGNORE_NONE;
|
||||||
|
|
||||||
|
if (srcRGB == VK_BLEND_FACTOR_SRC_ALPHA_SATURATE &&
|
||||||
|
(dstRGB == VK_BLEND_FACTOR_ZERO || dstRGB == VK_BLEND_FACTOR_SRC_ALPHA ||
|
||||||
|
dstRGB == VK_BLEND_FACTOR_SRC_ALPHA_SATURATE))
|
||||||
|
dstRGB_opt = V_028760_BLEND_OPT_PRESERVE_NONE_IGNORE_A0;
|
||||||
|
|
||||||
|
/* Set the final value. */
|
||||||
|
sx_mrt_blend_opt[i] =
|
||||||
|
S_028760_COLOR_SRC_OPT(srcRGB_opt) | S_028760_COLOR_DST_OPT(dstRGB_opt) |
|
||||||
|
S_028760_COLOR_COMB_FCN(si_translate_blend_opt_function(eqRGB)) |
|
||||||
|
S_028760_ALPHA_SRC_OPT(srcA_opt) | S_028760_ALPHA_DST_OPT(dstA_opt) |
|
||||||
|
S_028760_ALPHA_COMB_FCN(si_translate_blend_opt_function(eqA));
|
||||||
|
|
||||||
|
blend_cntl |= S_028780_ENABLE(1);
|
||||||
|
blend_cntl |= S_028780_COLOR_COMB_FCN(si_translate_blend_function(eqRGB));
|
||||||
|
blend_cntl |= S_028780_COLOR_SRCBLEND(si_translate_blend_factor(gfx_level, srcRGB));
|
||||||
|
blend_cntl |= S_028780_COLOR_DESTBLEND(si_translate_blend_factor(gfx_level, dstRGB));
|
||||||
|
if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) {
|
||||||
|
blend_cntl |= S_028780_SEPARATE_ALPHA_BLEND(1);
|
||||||
|
blend_cntl |= S_028780_ALPHA_COMB_FCN(si_translate_blend_function(eqA));
|
||||||
|
blend_cntl |= S_028780_ALPHA_SRCBLEND(si_translate_blend_factor(gfx_level, srcA));
|
||||||
|
blend_cntl |= S_028780_ALPHA_DESTBLEND(si_translate_blend_factor(gfx_level, dstA));
|
||||||
|
}
|
||||||
|
cb_blend_control[i] = blend_cntl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pdevice->rad_info.has_rbplus) {
|
||||||
|
/* Disable RB+ blend optimizations for dual source blending. */
|
||||||
|
if (mrt0_is_dual_src) {
|
||||||
|
for (unsigned i = 0; i < MAX_RTS; i++) {
|
||||||
|
sx_mrt_blend_opt[i] = S_028760_COLOR_COMB_FCN(V_028760_OPT_COMB_NONE) |
|
||||||
|
S_028760_ALPHA_COMB_FCN(V_028760_OPT_COMB_NONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4123,13 +4226,25 @@ lookup_ps_epilog(struct radv_cmd_buffer *cmd_buffer)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = 0; i < MAX_RTS; i++) {
|
for (unsigned i = 0; i < MAX_RTS; i++) {
|
||||||
|
VkBlendOp eqRGB = d->vk.cb.attachments[i].color_blend_op;
|
||||||
|
VkBlendFactor srcRGB = d->vk.cb.attachments[i].src_color_blend_factor;
|
||||||
|
VkBlendFactor dstRGB = d->vk.cb.attachments[i].dst_color_blend_factor;
|
||||||
|
|
||||||
state.color_write_mask |= d->vk.cb.attachments[i].write_mask << (4 * i);
|
state.color_write_mask |= d->vk.cb.attachments[i].write_mask << (4 * i);
|
||||||
state.color_blend_enable |= d->vk.cb.attachments[i].blend_enable << (4 * i);
|
state.color_blend_enable |= d->vk.cb.attachments[i].blend_enable << (4 * i);
|
||||||
|
|
||||||
|
radv_normalize_blend_factor(eqRGB, &srcRGB, &dstRGB);
|
||||||
|
|
||||||
|
if (srcRGB == VK_BLEND_FACTOR_SRC_ALPHA || dstRGB == VK_BLEND_FACTOR_SRC_ALPHA ||
|
||||||
|
srcRGB == VK_BLEND_FACTOR_SRC_ALPHA_SATURATE ||
|
||||||
|
dstRGB == VK_BLEND_FACTOR_SRC_ALPHA_SATURATE ||
|
||||||
|
srcRGB == VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA ||
|
||||||
|
dstRGB == VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA)
|
||||||
|
state.need_src_alpha |= 1 << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
state.mrt0_is_dual_src = pipeline->mrt0_is_dual_src;
|
state.mrt0_is_dual_src = radv_is_mrt0_dual_src(cmd_buffer);
|
||||||
|
|
||||||
state.need_src_alpha = pipeline->need_src_alpha;
|
|
||||||
if (d->vk.ms.alpha_to_coverage_enable) {
|
if (d->vk.ms.alpha_to_coverage_enable) {
|
||||||
/* Select a color export format with alpha when alpha to coverage is enabled. */
|
/* Select a color export format with alpha when alpha to coverage is enabled. */
|
||||||
state.need_src_alpha |= 0x1;
|
state.need_src_alpha |= 0x1;
|
||||||
@@ -4316,7 +4431,9 @@ radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer, bool pip
|
|||||||
radv_emit_clipping(cmd_buffer);
|
radv_emit_clipping(cmd_buffer);
|
||||||
|
|
||||||
if (states & (RADV_CMD_DIRTY_DYNAMIC_LOGIC_OP | RADV_CMD_DIRTY_DYNAMIC_LOGIC_OP_ENABLE |
|
if (states & (RADV_CMD_DIRTY_DYNAMIC_LOGIC_OP | RADV_CMD_DIRTY_DYNAMIC_LOGIC_OP_ENABLE |
|
||||||
RADV_CMD_DIRTY_DYNAMIC_COLOR_WRITE_MASK))
|
RADV_CMD_DIRTY_DYNAMIC_COLOR_WRITE_MASK |
|
||||||
|
RADV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_ENABLE |
|
||||||
|
RADV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_EQUATION))
|
||||||
radv_emit_logic_op(cmd_buffer);
|
radv_emit_logic_op(cmd_buffer);
|
||||||
|
|
||||||
if (states & (RADV_CMD_DIRTY_DYNAMIC_COLOR_WRITE_ENABLE |
|
if (states & (RADV_CMD_DIRTY_DYNAMIC_COLOR_WRITE_ENABLE |
|
||||||
@@ -4342,8 +4459,10 @@ radv_cmd_buffer_flush_dynamic_state(struct radv_cmd_buffer *cmd_buffer, bool pip
|
|||||||
RADV_CMD_DIRTY_DYNAMIC_DEPTH_CLIP_ENABLE))
|
RADV_CMD_DIRTY_DYNAMIC_DEPTH_CLIP_ENABLE))
|
||||||
radv_emit_depth_clamp_enable(cmd_buffer);
|
radv_emit_depth_clamp_enable(cmd_buffer);
|
||||||
|
|
||||||
if (states & RADV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_ENABLE)
|
if (states & (RADV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_ENABLE |
|
||||||
radv_emit_color_blend_enable(cmd_buffer);
|
RADV_CMD_DIRTY_DYNAMIC_COLOR_WRITE_MASK |
|
||||||
|
RADV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_EQUATION))
|
||||||
|
radv_emit_color_blend(cmd_buffer);
|
||||||
|
|
||||||
if (states & (RADV_CMD_DIRTY_DYNAMIC_RASTERIZATION_SAMPLES |
|
if (states & (RADV_CMD_DIRTY_DYNAMIC_RASTERIZATION_SAMPLES |
|
||||||
RADV_CMD_DIRTY_DYNAMIC_LINE_RASTERIZATION_MODE))
|
RADV_CMD_DIRTY_DYNAMIC_LINE_RASTERIZATION_MODE))
|
||||||
@@ -6985,6 +7104,35 @@ radv_CmdSetLineRasterizationModeEXT(VkCommandBuffer commandBuffer,
|
|||||||
state->dirty |= RADV_CMD_DIRTY_DYNAMIC_LINE_RASTERIZATION_MODE;
|
state->dirty |= RADV_CMD_DIRTY_DYNAMIC_LINE_RASTERIZATION_MODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VKAPI_ATTR void VKAPI_CALL
|
||||||
|
radv_CmdSetColorBlendEquationEXT(VkCommandBuffer commandBuffer, uint32_t firstAttachment,
|
||||||
|
uint32_t attachmentCount,
|
||||||
|
const VkColorBlendEquationEXT *pColorBlendEquations)
|
||||||
|
{
|
||||||
|
RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||||
|
struct radv_cmd_state *state = &cmd_buffer->state;
|
||||||
|
|
||||||
|
assert(firstAttachment + attachmentCount <= MAX_RTS);
|
||||||
|
for (uint32_t i = 0; i < attachmentCount; i++) {
|
||||||
|
unsigned idx = firstAttachment + i;
|
||||||
|
|
||||||
|
state->dynamic.vk.cb.attachments[idx].src_color_blend_factor =
|
||||||
|
pColorBlendEquations[i].srcColorBlendFactor;
|
||||||
|
state->dynamic.vk.cb.attachments[idx].dst_color_blend_factor =
|
||||||
|
pColorBlendEquations[i].dstColorBlendFactor;
|
||||||
|
state->dynamic.vk.cb.attachments[idx].color_blend_op =
|
||||||
|
pColorBlendEquations[i].colorBlendOp;
|
||||||
|
state->dynamic.vk.cb.attachments[idx].src_alpha_blend_factor =
|
||||||
|
pColorBlendEquations[i].srcAlphaBlendFactor;
|
||||||
|
state->dynamic.vk.cb.attachments[idx].dst_alpha_blend_factor =
|
||||||
|
pColorBlendEquations[i].dstAlphaBlendFactor;
|
||||||
|
state->dynamic.vk.cb.attachments[idx].alpha_blend_op =
|
||||||
|
pColorBlendEquations[i].alphaBlendOp;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->dirty |= RADV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_EQUATION;
|
||||||
|
}
|
||||||
|
|
||||||
VKAPI_ATTR void VKAPI_CALL
|
VKAPI_ATTR void VKAPI_CALL
|
||||||
radv_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount,
|
radv_CmdExecuteCommands(VkCommandBuffer commandBuffer, uint32_t commandBufferCount,
|
||||||
const VkCommandBuffer *pCmdBuffers)
|
const VkCommandBuffer *pCmdBuffers)
|
||||||
|
@@ -454,100 +454,7 @@ radv_pipeline_init_blend_state(struct radv_graphics_pipeline *pipeline,
|
|||||||
const struct vk_graphics_pipeline_state *state,
|
const struct vk_graphics_pipeline_state *state,
|
||||||
const struct radv_pipeline_key *key)
|
const struct radv_pipeline_key *key)
|
||||||
{
|
{
|
||||||
const struct radv_device *device = pipeline->base.device;
|
|
||||||
struct radv_blend_state blend = {0};
|
struct radv_blend_state blend = {0};
|
||||||
const enum amd_gfx_level gfx_level = device->physical_device->rad_info.gfx_level;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (state->cb) {
|
|
||||||
for (i = 0; i < state->cb->attachment_count; i++) {
|
|
||||||
unsigned blend_cntl = 0;
|
|
||||||
unsigned srcRGB_opt, dstRGB_opt, srcA_opt, dstA_opt;
|
|
||||||
VkBlendOp eqRGB = state->cb->attachments[i].color_blend_op;
|
|
||||||
VkBlendFactor srcRGB = state->cb->attachments[i].src_color_blend_factor;
|
|
||||||
VkBlendFactor dstRGB = state->cb->attachments[i].dst_color_blend_factor;
|
|
||||||
VkBlendOp eqA = state->cb->attachments[i].alpha_blend_op;
|
|
||||||
VkBlendFactor srcA = state->cb->attachments[i].src_alpha_blend_factor;
|
|
||||||
VkBlendFactor dstA = state->cb->attachments[i].dst_alpha_blend_factor;
|
|
||||||
|
|
||||||
if (!state->cb->attachments[i].write_mask)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Ignore other blend targets if dual-source blending
|
|
||||||
* is enabled to prevent wrong behaviour.
|
|
||||||
*/
|
|
||||||
if (i > 0 && key->ps.epilog.mrt0_is_dual_src)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!state->cb->attachments[i].blend_enable) {
|
|
||||||
pipeline->cb_blend_control[i] = blend_cntl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
radv_normalize_blend_factor(eqRGB, &srcRGB, &dstRGB);
|
|
||||||
radv_normalize_blend_factor(eqA, &srcA, &dstA);
|
|
||||||
|
|
||||||
/* Blending optimizations for RB+.
|
|
||||||
* These transformations don't change the behavior.
|
|
||||||
*
|
|
||||||
* First, get rid of DST in the blend factors:
|
|
||||||
* func(src * DST, dst * 0) ---> func(src * 0, dst * SRC)
|
|
||||||
*/
|
|
||||||
si_blend_remove_dst(&eqRGB, &srcRGB, &dstRGB, VK_BLEND_FACTOR_DST_COLOR,
|
|
||||||
VK_BLEND_FACTOR_SRC_COLOR);
|
|
||||||
|
|
||||||
si_blend_remove_dst(&eqA, &srcA, &dstA, VK_BLEND_FACTOR_DST_COLOR,
|
|
||||||
VK_BLEND_FACTOR_SRC_COLOR);
|
|
||||||
|
|
||||||
si_blend_remove_dst(&eqA, &srcA, &dstA, VK_BLEND_FACTOR_DST_ALPHA,
|
|
||||||
VK_BLEND_FACTOR_SRC_ALPHA);
|
|
||||||
|
|
||||||
/* Look up the ideal settings from tables. */
|
|
||||||
srcRGB_opt = si_translate_blend_opt_factor(srcRGB, false);
|
|
||||||
dstRGB_opt = si_translate_blend_opt_factor(dstRGB, false);
|
|
||||||
srcA_opt = si_translate_blend_opt_factor(srcA, true);
|
|
||||||
dstA_opt = si_translate_blend_opt_factor(dstA, true);
|
|
||||||
|
|
||||||
/* Handle interdependencies. */
|
|
||||||
if (si_blend_factor_uses_dst(srcRGB))
|
|
||||||
dstRGB_opt = V_028760_BLEND_OPT_PRESERVE_NONE_IGNORE_NONE;
|
|
||||||
if (si_blend_factor_uses_dst(srcA))
|
|
||||||
dstA_opt = V_028760_BLEND_OPT_PRESERVE_NONE_IGNORE_NONE;
|
|
||||||
|
|
||||||
if (srcRGB == VK_BLEND_FACTOR_SRC_ALPHA_SATURATE &&
|
|
||||||
(dstRGB == VK_BLEND_FACTOR_ZERO || dstRGB == VK_BLEND_FACTOR_SRC_ALPHA ||
|
|
||||||
dstRGB == VK_BLEND_FACTOR_SRC_ALPHA_SATURATE))
|
|
||||||
dstRGB_opt = V_028760_BLEND_OPT_PRESERVE_NONE_IGNORE_A0;
|
|
||||||
|
|
||||||
/* Set the final value. */
|
|
||||||
pipeline->sx_mrt_blend_opt[i] =
|
|
||||||
S_028760_COLOR_SRC_OPT(srcRGB_opt) | S_028760_COLOR_DST_OPT(dstRGB_opt) |
|
|
||||||
S_028760_COLOR_COMB_FCN(si_translate_blend_opt_function(eqRGB)) |
|
|
||||||
S_028760_ALPHA_SRC_OPT(srcA_opt) | S_028760_ALPHA_DST_OPT(dstA_opt) |
|
|
||||||
S_028760_ALPHA_COMB_FCN(si_translate_blend_opt_function(eqA));
|
|
||||||
|
|
||||||
blend_cntl |= S_028780_COLOR_COMB_FCN(si_translate_blend_function(eqRGB));
|
|
||||||
blend_cntl |= S_028780_COLOR_SRCBLEND(si_translate_blend_factor(gfx_level, srcRGB));
|
|
||||||
blend_cntl |= S_028780_COLOR_DESTBLEND(si_translate_blend_factor(gfx_level, dstRGB));
|
|
||||||
if (srcA != srcRGB || dstA != dstRGB || eqA != eqRGB) {
|
|
||||||
blend_cntl |= S_028780_SEPARATE_ALPHA_BLEND(1);
|
|
||||||
blend_cntl |= S_028780_ALPHA_COMB_FCN(si_translate_blend_function(eqA));
|
|
||||||
blend_cntl |= S_028780_ALPHA_SRCBLEND(si_translate_blend_factor(gfx_level, srcA));
|
|
||||||
blend_cntl |= S_028780_ALPHA_DESTBLEND(si_translate_blend_factor(gfx_level, dstA));
|
|
||||||
}
|
|
||||||
pipeline->cb_blend_control[i] = blend_cntl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device->physical_device->rad_info.has_rbplus) {
|
|
||||||
/* Disable RB+ blend optimizations for dual source blending. */
|
|
||||||
if (key->ps.epilog.mrt0_is_dual_src) {
|
|
||||||
for (i = 0; i < 8; i++) {
|
|
||||||
pipeline->sx_mrt_blend_opt[i] = S_028760_COLOR_COMB_FCN(V_028760_OPT_COMB_NONE) |
|
|
||||||
S_028760_ALPHA_COMB_FCN(V_028760_OPT_COMB_NONE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
blend.cb_shader_mask = ac_get_cb_shader_mask(key->ps.epilog.spi_shader_col_format);
|
blend.cb_shader_mask = ac_get_cb_shader_mask(key->ps.epilog.spi_shader_col_format);
|
||||||
blend.spi_shader_col_format = key->ps.epilog.spi_shader_col_format;
|
blend.spi_shader_col_format = key->ps.epilog.spi_shader_col_format;
|
||||||
@@ -768,6 +675,8 @@ radv_dynamic_state_mask(VkDynamicState state)
|
|||||||
return RADV_DYNAMIC_RASTERIZATION_SAMPLES;
|
return RADV_DYNAMIC_RASTERIZATION_SAMPLES;
|
||||||
case VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT:
|
case VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT:
|
||||||
return RADV_DYNAMIC_LINE_RASTERIZATION_MODE;
|
return RADV_DYNAMIC_LINE_RASTERIZATION_MODE;
|
||||||
|
case VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT:
|
||||||
|
return RADV_DYNAMIC_COLOR_BLEND_EQUATION;
|
||||||
default:
|
default:
|
||||||
unreachable("Unhandled dynamic state");
|
unreachable("Unhandled dynamic state");
|
||||||
}
|
}
|
||||||
@@ -1365,6 +1274,19 @@ radv_pipeline_init_dynamic_state(struct radv_graphics_pipeline *pipeline,
|
|||||||
dynamic->vk.rs.line.mode = state->rs->line.mode;
|
dynamic->vk.rs.line.mode = state->rs->line.mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (radv_pipeline_has_color_attachments(state->rp) && states & RADV_DYNAMIC_COLOR_BLEND_EQUATION) {
|
||||||
|
for (unsigned i = 0; i < state->cb->attachment_count; i++) {
|
||||||
|
const struct vk_color_blend_attachment_state *att = &state->cb->attachments[i];
|
||||||
|
|
||||||
|
dynamic->vk.cb.attachments[i].src_color_blend_factor = att->src_color_blend_factor;
|
||||||
|
dynamic->vk.cb.attachments[i].dst_color_blend_factor = att->dst_color_blend_factor;
|
||||||
|
dynamic->vk.cb.attachments[i].color_blend_op = att->color_blend_op;
|
||||||
|
dynamic->vk.cb.attachments[i].src_alpha_blend_factor = att->src_alpha_blend_factor;
|
||||||
|
dynamic->vk.cb.attachments[i].dst_alpha_blend_factor = att->dst_alpha_blend_factor;
|
||||||
|
dynamic->vk.cb.attachments[i].alpha_blend_op = att->alpha_blend_op;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pipeline->dynamic_state.mask = states;
|
pipeline->dynamic_state.mask = states;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2258,7 +2180,6 @@ radv_generate_ps_epilog_key(const struct radv_graphics_pipeline *pipeline,
|
|||||||
key.color_is_int10 = device->physical_device->rad_info.gfx_level < GFX8 ? is_int10 : 0;
|
key.color_is_int10 = device->physical_device->rad_info.gfx_level < GFX8 ? is_int10 : 0;
|
||||||
key.enable_mrt_output_nan_fixup = device->instance->enable_mrt_output_nan_fixup ? is_float32 : 0;
|
key.enable_mrt_output_nan_fixup = device->instance->enable_mrt_output_nan_fixup ? is_float32 : 0;
|
||||||
key.mrt0_is_dual_src = state->mrt0_is_dual_src;
|
key.mrt0_is_dual_src = state->mrt0_is_dual_src;
|
||||||
key.need_src_alpha = state->need_src_alpha;
|
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
@@ -5055,9 +4976,6 @@ radv_graphics_pipeline_init(struct radv_graphics_pipeline *pipeline, struct radv
|
|||||||
/* Copy the non-compacted SPI_SHADER_COL_FORMAT which is used to emit RBPLUS state. */
|
/* Copy the non-compacted SPI_SHADER_COL_FORMAT which is used to emit RBPLUS state. */
|
||||||
pipeline->col_format_non_compacted = blend.spi_shader_col_format;
|
pipeline->col_format_non_compacted = blend.spi_shader_col_format;
|
||||||
|
|
||||||
pipeline->mrt0_is_dual_src = key.ps.epilog.mrt0_is_dual_src;
|
|
||||||
pipeline->need_src_alpha = key.ps.epilog.need_src_alpha;
|
|
||||||
|
|
||||||
struct radv_shader *ps = pipeline->base.shaders[MESA_SHADER_FRAGMENT];
|
struct radv_shader *ps = pipeline->base.shaders[MESA_SHADER_FRAGMENT];
|
||||||
bool enable_mrt_compaction = !key.ps.epilog.mrt0_is_dual_src && !ps->info.ps.has_epilog;
|
bool enable_mrt_compaction = !key.ps.epilog.mrt0_is_dual_src && !ps->info.ps.has_epilog;
|
||||||
if (enable_mrt_compaction) {
|
if (enable_mrt_compaction) {
|
||||||
|
@@ -1185,7 +1185,8 @@ enum radv_dynamic_state_bits {
|
|||||||
RADV_DYNAMIC_COLOR_BLEND_ENABLE = 1ull << 42,
|
RADV_DYNAMIC_COLOR_BLEND_ENABLE = 1ull << 42,
|
||||||
RADV_DYNAMIC_RASTERIZATION_SAMPLES = 1ull << 43,
|
RADV_DYNAMIC_RASTERIZATION_SAMPLES = 1ull << 43,
|
||||||
RADV_DYNAMIC_LINE_RASTERIZATION_MODE = 1ull << 44,
|
RADV_DYNAMIC_LINE_RASTERIZATION_MODE = 1ull << 44,
|
||||||
RADV_DYNAMIC_ALL = (1ull << 45) - 1,
|
RADV_DYNAMIC_COLOR_BLEND_EQUATION = 1ull << 45,
|
||||||
|
RADV_DYNAMIC_ALL = (1ull << 46) - 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum radv_cmd_dirty_bits {
|
enum radv_cmd_dirty_bits {
|
||||||
@@ -1236,14 +1237,15 @@ enum radv_cmd_dirty_bits {
|
|||||||
RADV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_ENABLE = 1ull << 42,
|
RADV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_ENABLE = 1ull << 42,
|
||||||
RADV_CMD_DIRTY_DYNAMIC_RASTERIZATION_SAMPLES = 1ull << 43,
|
RADV_CMD_DIRTY_DYNAMIC_RASTERIZATION_SAMPLES = 1ull << 43,
|
||||||
RADV_CMD_DIRTY_DYNAMIC_LINE_RASTERIZATION_MODE = 1ull << 44,
|
RADV_CMD_DIRTY_DYNAMIC_LINE_RASTERIZATION_MODE = 1ull << 44,
|
||||||
RADV_CMD_DIRTY_DYNAMIC_ALL = (1ull << 45) - 1,
|
RADV_CMD_DIRTY_DYNAMIC_COLOR_BLEND_EQUATION = 1ull << 45,
|
||||||
RADV_CMD_DIRTY_PIPELINE = 1ull << 45,
|
RADV_CMD_DIRTY_DYNAMIC_ALL = (1ull << 46) - 1,
|
||||||
RADV_CMD_DIRTY_INDEX_BUFFER = 1ull << 46,
|
RADV_CMD_DIRTY_PIPELINE = 1ull << 46,
|
||||||
RADV_CMD_DIRTY_FRAMEBUFFER = 1ull << 47,
|
RADV_CMD_DIRTY_INDEX_BUFFER = 1ull << 47,
|
||||||
RADV_CMD_DIRTY_VERTEX_BUFFER = 1ull << 48,
|
RADV_CMD_DIRTY_FRAMEBUFFER = 1ull << 48,
|
||||||
RADV_CMD_DIRTY_STREAMOUT_BUFFER = 1ull << 49,
|
RADV_CMD_DIRTY_VERTEX_BUFFER = 1ull << 49,
|
||||||
RADV_CMD_DIRTY_GUARDBAND = 1ull << 50,
|
RADV_CMD_DIRTY_STREAMOUT_BUFFER = 1ull << 50,
|
||||||
RADV_CMD_DIRTY_RBPLUS = 1ull << 51,
|
RADV_CMD_DIRTY_GUARDBAND = 1ull << 51,
|
||||||
|
RADV_CMD_DIRTY_RBPLUS = 1ull << 52,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum radv_cmd_flush_bits {
|
enum radv_cmd_flush_bits {
|
||||||
@@ -2064,8 +2066,6 @@ struct radv_graphics_pipeline {
|
|||||||
struct radv_ia_multi_vgt_param_helpers ia_multi_vgt_param;
|
struct radv_ia_multi_vgt_param_helpers ia_multi_vgt_param;
|
||||||
uint8_t vtx_emit_num;
|
uint8_t vtx_emit_num;
|
||||||
uint64_t needed_dynamic_state;
|
uint64_t needed_dynamic_state;
|
||||||
unsigned cb_blend_control[MAX_RTS];
|
|
||||||
unsigned sx_mrt_blend_opt[MAX_RTS];
|
|
||||||
uint32_t binding_stride[MAX_VBS];
|
uint32_t binding_stride[MAX_VBS];
|
||||||
uint8_t attrib_bindings[MAX_VERTEX_ATTRIBS];
|
uint8_t attrib_bindings[MAX_VERTEX_ATTRIBS];
|
||||||
uint32_t attrib_ends[MAX_VERTEX_ATTRIBS];
|
uint32_t attrib_ends[MAX_VERTEX_ATTRIBS];
|
||||||
@@ -2084,8 +2084,6 @@ struct radv_graphics_pipeline {
|
|||||||
/* Used for rbplus */
|
/* Used for rbplus */
|
||||||
uint32_t col_format_non_compacted;
|
uint32_t col_format_non_compacted;
|
||||||
|
|
||||||
bool mrt0_is_dual_src;
|
|
||||||
uint8_t need_src_alpha;
|
|
||||||
bool need_null_export_workaround;
|
bool need_null_export_workaround;
|
||||||
|
|
||||||
bool uses_drawid;
|
bool uses_drawid;
|
||||||
|
@@ -61,8 +61,6 @@ struct radv_ps_epilog_key {
|
|||||||
uint8_t enable_mrt_output_nan_fixup;
|
uint8_t enable_mrt_output_nan_fixup;
|
||||||
|
|
||||||
bool mrt0_is_dual_src;
|
bool mrt0_is_dual_src;
|
||||||
|
|
||||||
uint8_t need_src_alpha; /* XXX: Remove this when color blend equations are dynamic! */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct radv_pipeline_key {
|
struct radv_pipeline_key {
|
||||||
|
Reference in New Issue
Block a user