anv: stop tracking color blend state in the pipeline
Now that all color blend bits are dynamic, emit_cb_state() is doing
almost nothing and half of that is wrong.
In the case that color write enable is dynamic, at the time the pipeline
state is emitted, it sees all the color attachments as having write
disabled and stores the WriteDisabled bit for each channel.
When all dynamic state is flushed, we have the right values already but
the values recorded into the command buffer get ORed with the ones
stored in the pipeline, and so WriteDisabled tag along when they
shouldn't.
Since all disabled color attachments are handled already when dynamic
state is flushed, there's no point in doing so at pipeline creation
time too. And since the only other thing done by emit_cb_state() is
writing three hardcoded values, they might as well be taken care of in
the same place as everything else.
Fixes CTS from the future:
dEQP-VK.pipeline.*.extended_dynamic_state.*.color_blend_equation_*dynamic*
dEQP-VK.pipeline.*.extended_dynamic_state.*.color_blend_all_*
Fixes: fc3fd7c69e
(anv: dynamic color write mask)
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Tapani Pälli <tapani.palli@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21509>
This commit is contained in:
@@ -3143,7 +3143,6 @@ struct anv_graphics_pipeline {
|
||||
uint32_t sf[4];
|
||||
uint32_t raster[5];
|
||||
uint32_t wm[2];
|
||||
uint32_t blend_state[1 + MAX_RTS * 2];
|
||||
uint32_t streamout_state[5];
|
||||
uint32_t hs[9];
|
||||
} gfx8;
|
||||
|
@@ -842,77 +842,6 @@ const uint32_t genX(vk_to_intel_primitive_type)[] = {
|
||||
[VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY] = _3DPRIM_TRISTRIP_ADJ,
|
||||
};
|
||||
|
||||
static inline uint32_t *
|
||||
write_disabled_blend(uint32_t *state)
|
||||
{
|
||||
struct GENX(BLEND_STATE_ENTRY) entry = {
|
||||
.WriteDisableAlpha = true,
|
||||
.WriteDisableRed = true,
|
||||
.WriteDisableGreen = true,
|
||||
.WriteDisableBlue = true,
|
||||
};
|
||||
GENX(BLEND_STATE_ENTRY_pack)(NULL, state, &entry);
|
||||
return state + GENX(BLEND_STATE_ENTRY_length);
|
||||
}
|
||||
|
||||
static void
|
||||
emit_cb_state(struct anv_graphics_pipeline *pipeline,
|
||||
const struct vk_color_blend_state *cb,
|
||||
const struct vk_multisample_state *ms)
|
||||
{
|
||||
uint32_t surface_count = 0;
|
||||
struct anv_pipeline_bind_map *map;
|
||||
if (anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT)) {
|
||||
map = &pipeline->shaders[MESA_SHADER_FRAGMENT]->bind_map;
|
||||
surface_count = map->surface_count;
|
||||
}
|
||||
|
||||
uint32_t *state_pos = pipeline->gfx8.blend_state;
|
||||
|
||||
state_pos += GENX(BLEND_STATE_length);
|
||||
for (unsigned i = 0; i < surface_count; i++) {
|
||||
struct anv_pipeline_binding *binding = &map->surface_to_descriptor[i];
|
||||
|
||||
/* All color attachments are at the beginning of the binding table */
|
||||
if (binding->set != ANV_DESCRIPTOR_SET_COLOR_ATTACHMENTS)
|
||||
break;
|
||||
|
||||
/* We can have at most 8 attachments */
|
||||
assert(i < MAX_RTS);
|
||||
|
||||
if (cb == NULL || binding->index >= cb->attachment_count) {
|
||||
state_pos = write_disabled_blend(state_pos);
|
||||
continue;
|
||||
}
|
||||
|
||||
struct GENX(BLEND_STATE_ENTRY) entry = {
|
||||
/* Vulkan specification 1.2.168, VkLogicOp:
|
||||
*
|
||||
* "Logical operations are controlled by the logicOpEnable and
|
||||
* logicOp members of VkPipelineColorBlendStateCreateInfo. If
|
||||
* logicOpEnable is VK_TRUE, then a logical operation selected by
|
||||
* logicOp is applied between each color attachment and the
|
||||
* fragment’s corresponding output value, and blending of all
|
||||
* attachments is treated as if it were disabled."
|
||||
*
|
||||
* From the Broadwell PRM Volume 2d: Command Reference: Structures:
|
||||
* BLEND_STATE_ENTRY:
|
||||
*
|
||||
* "Enabling LogicOp and Color Buffer Blending at the same time is
|
||||
* UNDEFINED"
|
||||
*
|
||||
* Above is handled during emit since these states are dynamic.
|
||||
*/
|
||||
.ColorClampRange = COLORCLAMP_RTFORMAT,
|
||||
.PreBlendColorClampEnable = true,
|
||||
.PostBlendColorClampEnable = true,
|
||||
};
|
||||
|
||||
GENX(BLEND_STATE_ENTRY_pack)(NULL, state_pos, &entry);
|
||||
state_pos += GENX(BLEND_STATE_ENTRY_length);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
emit_3dstate_clip(struct anv_graphics_pipeline *pipeline,
|
||||
const struct vk_input_assembly_state *ia,
|
||||
@@ -1872,7 +1801,6 @@ genX(graphics_pipeline_emit)(struct anv_graphics_pipeline *pipeline,
|
||||
emit_rs_state(pipeline, state->ia, state->rs, state->ms, state->rp,
|
||||
urb_deref_block_size);
|
||||
emit_ms_state(pipeline, state->ms);
|
||||
emit_cb_state(pipeline, state->cb, state->ms);
|
||||
compute_kill_pixel(pipeline, state->ms, state->rp);
|
||||
|
||||
emit_3dstate_clip(pipeline, state->ia, state->vp, state->rs);
|
||||
|
@@ -724,10 +724,14 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
|
||||
anv_pipeline_has_stage(pipeline, MESA_SHADER_FRAGMENT) &&
|
||||
(color_writes & ((1u << state->color_att_count) - 1)) != 0;
|
||||
|
||||
uint32_t blend_dws[GENX(BLEND_STATE_length) +
|
||||
MAX_RTS * GENX(BLEND_STATE_ENTRY_length)];
|
||||
uint32_t *dws = blend_dws;
|
||||
memset(blend_dws, 0, sizeof(blend_dws));
|
||||
uint32_t num_dwords = GENX(BLEND_STATE_length) +
|
||||
GENX(BLEND_STATE_ENTRY_length) * MAX_RTS;
|
||||
struct anv_state blend_states =
|
||||
anv_cmd_buffer_alloc_dynamic_state(cmd_buffer,
|
||||
num_dwords * 4,
|
||||
64);
|
||||
|
||||
uint32_t *dws = blend_states.map;
|
||||
|
||||
struct GENX(BLEND_STATE) blend_state = {
|
||||
.AlphaToCoverageEnable = dyn->ms.alpha_to_coverage_enable,
|
||||
@@ -756,10 +760,29 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
|
||||
.WriteDisableBlue = write_disabled ||
|
||||
(dyn->cb.attachments[i].write_mask &
|
||||
VK_COLOR_COMPONENT_B_BIT) == 0,
|
||||
/* Vulkan specification 1.2.168, VkLogicOp:
|
||||
*
|
||||
* "Logical operations are controlled by the logicOpEnable and
|
||||
* logicOp members of VkPipelineColorBlendStateCreateInfo. If
|
||||
* logicOpEnable is VK_TRUE, then a logical operation selected
|
||||
* by logicOp is applied between each color attachment and the
|
||||
* fragment’s corresponding output value, and blending of all
|
||||
* attachments is treated as if it were disabled."
|
||||
*
|
||||
* From the Broadwell PRM Volume 2d: Command Reference:
|
||||
* Structures: BLEND_STATE_ENTRY:
|
||||
*
|
||||
* "Enabling LogicOp and Color Buffer Blending at the same time
|
||||
* is UNDEFINED"
|
||||
*/
|
||||
.LogicOpFunction = genX(vk_to_intel_logic_op)[dyn->cb.logic_op],
|
||||
.LogicOpEnable = dyn->cb.logic_op_enable,
|
||||
.ColorBufferBlendEnable =
|
||||
!dyn->cb.logic_op_enable && dyn->cb.attachments[i].blend_enable,
|
||||
|
||||
.ColorClampRange = COLORCLAMP_RTFORMAT,
|
||||
.PreBlendColorClampEnable = true,
|
||||
.PostBlendColorClampEnable = true,
|
||||
};
|
||||
|
||||
/* Setup blend equation. */
|
||||
@@ -827,7 +850,7 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
|
||||
}
|
||||
|
||||
/* Generate blend state after entries. */
|
||||
GENX(BLEND_STATE_pack)(NULL, blend_dws, &blend_state);
|
||||
GENX(BLEND_STATE_pack)(NULL, blend_states.map, &blend_state);
|
||||
|
||||
/* 3DSTATE_PS_BLEND to be consistent with the rest of the
|
||||
* BLEND_STATE_ENTRY.
|
||||
@@ -844,12 +867,6 @@ genX(cmd_buffer_flush_dynamic_state)(struct anv_cmd_buffer *cmd_buffer)
|
||||
blend.AlphaToCoverageEnable = dyn->ms.alpha_to_coverage_enable;
|
||||
}
|
||||
|
||||
uint32_t num_dwords = GENX(BLEND_STATE_length) +
|
||||
GENX(BLEND_STATE_ENTRY_length) * MAX_RTS;
|
||||
|
||||
struct anv_state blend_states =
|
||||
anv_cmd_buffer_merge_dynamic(cmd_buffer, blend_dws,
|
||||
pipeline->gfx8.blend_state, num_dwords, 64);
|
||||
anv_batch_emit(&cmd_buffer->batch, GENX(3DSTATE_BLEND_STATE_POINTERS), bsp) {
|
||||
bsp.BlendStatePointer = blend_states.offset;
|
||||
bsp.BlendStatePointerValid = true;
|
||||
|
Reference in New Issue
Block a user