tu: Support color attachment remapping

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/31261>
This commit is contained in:
Connor Abbott 2024-02-08 07:49:06 -05:00 committed by Marge Bot
parent 5a4dff5922
commit d50eef5b06
3 changed files with 122 additions and 44 deletions

View file

@ -3365,6 +3365,26 @@ tu_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer,
} }
TU_GENX(tu_CmdClearDepthStencilImage); TU_GENX(tu_CmdClearDepthStencilImage);
/* CmdClearAttachments uses the original color attachment index instead of the
* remapped index used by the shader, and our MRTs use the remapped
* indices, so we have to remap them. We should always be able to find a
* shader attachment thanks to this VU:
*
* VUID-vkCmdClearAttachments-colorAttachment-09503
* "The colorAttachment member of each element of pAttachments must not
* identify a color attachment that is currently mapped to
* VK_ATTACHMENT_UNUSED in commandBuffer via
* VkRenderingAttachmentLocationInfoKHR"
*/
static unsigned
remap_attachment(struct tu_cmd_buffer *cmd, unsigned a)
{
unsigned i = cmd->vk.dynamic_graphics_state.cal.color_map[a];
assert(i != MESA_VK_ATTACHMENT_UNUSED &&
"app violates VUID-vkCmdClearAttachments-colorAttachment-09503");
return i;
}
template <chip CHIP> template <chip CHIP>
static void static void
tu_clear_sysmem_attachments(struct tu_cmd_buffer *cmd, tu_clear_sysmem_attachments(struct tu_cmd_buffer *cmd,
@ -3394,9 +3414,10 @@ tu_clear_sysmem_attachments(struct tu_cmd_buffer *cmd,
if (a == VK_ATTACHMENT_UNUSED) if (a == VK_ATTACHMENT_UNUSED)
continue; continue;
clear_rts |= 1 << c; uint32_t remapped = remap_attachment(cmd, c);
clear_components |= 0xf << (c * 4); clear_rts |= 1 << remapped;
memcpy(clear_value[c], &attachments[i].clearValue, 4 * sizeof(uint32_t)); clear_components |= 0xf << (remapped * 4);
memcpy(clear_value[remapped], &attachments[i].clearValue, 4 * sizeof(uint32_t));
} else { } else {
a = subpass->depth_stencil_attachment.attachment; a = subpass->depth_stencil_attachment.attachment;
if (a == VK_ATTACHMENT_UNUSED) if (a == VK_ATTACHMENT_UNUSED)

View file

@ -449,9 +449,42 @@ tu6_emit_mrt(struct tu_cmd_buffer *cmd,
enum a6xx_format mrt0_format = FMT6_NONE; enum a6xx_format mrt0_format = FMT6_NONE;
uint32_t written = 0;
for (uint32_t i = 0; i < subpass->color_count; ++i) { for (uint32_t i = 0; i < subpass->color_count; ++i) {
uint32_t a = subpass->color_attachments[i].attachment; uint32_t a = subpass->color_attachments[i].attachment;
if (a == VK_ATTACHMENT_UNUSED) { unsigned remapped = cmd->vk.dynamic_graphics_state.cal.color_map[i];
if (a == VK_ATTACHMENT_UNUSED ||
remapped == MESA_VK_ATTACHMENT_UNUSED)
continue;
const struct tu_image_view *iview = cmd->state.attachments[a];
tu_cs_emit_regs(cs,
RB_MRT_BUF_INFO(CHIP, remapped, .dword = iview->view.RB_MRT_BUF_INFO),
A6XX_RB_MRT_PITCH(remapped, iview->view.pitch),
A6XX_RB_MRT_ARRAY_PITCH(remapped, iview->view.layer_size),
A6XX_RB_MRT_BASE(remapped, .qword = tu_layer_address(&iview->view, 0)),
A6XX_RB_MRT_BASE_GMEM(remapped,
tu_attachment_gmem_offset(cmd, &cmd->state.pass->attachments[a], 0)
),
);
tu_cs_emit_regs(cs,
A6XX_SP_FS_MRT_REG(remapped, .dword = iview->view.SP_FS_MRT_REG));
tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_FLAG_BUFFER_ADDR(remapped), 3);
tu_cs_image_flag_ref(cs, &iview->view, 0);
if (remapped == 0)
mrt0_format = (enum a6xx_format) (iview->view.SP_FS_MRT_REG & 0xff);
written |= 1u << remapped;
}
u_foreach_bit (i, ~written) {
if (i >= subpass->color_count)
break;
/* From the VkPipelineRenderingCreateInfo definition: /* From the VkPipelineRenderingCreateInfo definition:
* *
* Valid formats indicate that an attachment can be used - but it * Valid formats indicate that an attachment can be used - but it
@ -474,29 +507,6 @@ tu6_emit_mrt(struct tu_cmd_buffer *cmd,
tu_cs_emit_regs(cs, tu_cs_emit_regs(cs,
A6XX_SP_FS_MRT_REG(i, .dword = 0)); A6XX_SP_FS_MRT_REG(i, .dword = 0));
continue;
}
const struct tu_image_view *iview = cmd->state.attachments[a];
tu_cs_emit_regs(cs,
RB_MRT_BUF_INFO(CHIP, i, .dword = iview->view.RB_MRT_BUF_INFO),
A6XX_RB_MRT_PITCH(i, iview->view.pitch),
A6XX_RB_MRT_ARRAY_PITCH(i, iview->view.layer_size),
A6XX_RB_MRT_BASE(i, .qword = tu_layer_address(&iview->view, 0)),
A6XX_RB_MRT_BASE_GMEM(i,
tu_attachment_gmem_offset(cmd, &cmd->state.pass->attachments[a], 0)
),
);
tu_cs_emit_regs(cs,
A6XX_SP_FS_MRT_REG(i, .dword = iview->view.SP_FS_MRT_REG));
tu_cs_emit_pkt4(cs, REG_A6XX_RB_MRT_FLAG_BUFFER_ADDR(i), 3);
tu_cs_image_flag_ref(cs, &iview->view, 0);
if (i == 0)
mrt0_format = (enum a6xx_format) (iview->view.SP_FS_MRT_REG & 0xff);
} }
tu_cs_emit_regs(cs, A6XX_GRAS_LRZ_MRT_BUF_INFO_0(.color_format = mrt0_format)); tu_cs_emit_regs(cs, A6XX_GRAS_LRZ_MRT_BUF_INFO_0(.color_format = mrt0_format));
@ -599,12 +609,14 @@ tu6_emit_render_cntl<A6XX>(struct tu_cmd_buffer *cmd,
uint32_t mrts_ubwc_enable = 0; uint32_t mrts_ubwc_enable = 0;
for (uint32_t i = 0; i < subpass->color_count; ++i) { for (uint32_t i = 0; i < subpass->color_count; ++i) {
uint32_t a = subpass->color_attachments[i].attachment; uint32_t a = subpass->color_attachments[i].attachment;
if (a == VK_ATTACHMENT_UNUSED) unsigned remapped = cmd->vk.dynamic_graphics_state.cal.color_map[i];
if (a == VK_ATTACHMENT_UNUSED ||
remapped == MESA_VK_ATTACHMENT_UNUSED)
continue; continue;
const struct tu_image_view *iview = cmd->state.attachments[a]; const struct tu_image_view *iview = cmd->state.attachments[a];
if (iview->view.ubwc_enabled) if (iview->view.ubwc_enabled)
mrts_ubwc_enable |= 1 << i; mrts_ubwc_enable |= 1 << remapped;
} }
cntl |= A6XX_RB_RENDER_CNTL_FLAG_MRTS(mrts_ubwc_enable); cntl |= A6XX_RB_RENDER_CNTL_FLAG_MRTS(mrts_ubwc_enable);
@ -4709,6 +4721,12 @@ tu_CmdBeginRendering(VkCommandBuffer commandBuffer,
cmd->state.attachments[a] = view; cmd->state.attachments[a] = view;
} }
const VkRenderingAttachmentLocationInfoKHR ral_info = {
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_LOCATION_INFO_KHR,
.colorAttachmentCount = pRenderingInfo->colorAttachmentCount,
};
vk_cmd_set_rendering_attachment_locations(&cmd->vk, &ral_info);
if (cmd->dynamic_pass.has_fdm) if (cmd->dynamic_pass.has_fdm)
cmd->patchpoints_ctx = ralloc_context(NULL); cmd->patchpoints_ctx = ralloc_context(NULL);
@ -4785,6 +4803,35 @@ tu_CmdBeginRendering(VkCommandBuffer commandBuffer,
} }
TU_GENX(tu_CmdBeginRendering); TU_GENX(tu_CmdBeginRendering);
template <chip CHIP>
VKAPI_ATTR void VKAPI_CALL
tu_CmdSetRenderingAttachmentLocationsKHR(
VkCommandBuffer commandBuffer,
const VkRenderingAttachmentLocationInfoKHR *pLocationInfo)
{
VK_FROM_HANDLE(tu_cmd_buffer, cmd, commandBuffer);
vk_common_CmdSetRenderingAttachmentLocationsKHR(commandBuffer, pLocationInfo);
tu6_emit_mrt<CHIP>(cmd, cmd->state.subpass, &cmd->draw_cs);
tu6_emit_render_cntl<CHIP>(cmd, cmd->state.subpass, &cmd->draw_cs, false);
/* Because this is just a remapping and not a different "reference", there
* doesn't need to be a barrier between accesses to the same attachment
* with a different index. This is different from "classic" renderpasses.
* Before a7xx the CCU includes the render target ID in the cache location
* calculation, so we need to manually flush/invalidate color CCU here
* since the same render target/attachment may be in a different location.
*/
if (cmd->device->physical_device->info->chip == 6) {
struct tu_cache_state *cache = &cmd->state.renderpass_cache;
tu_flush_for_access(cache, TU_ACCESS_CCU_COLOR_INCOHERENT_WRITE,
TU_ACCESS_CCU_COLOR_INCOHERENT_WRITE);
cache->flush_bits |= TU_CMD_FLAG_WAIT_FOR_IDLE;
}
}
TU_GENX(tu_CmdSetRenderingAttachmentLocationsKHR);
template <chip CHIP> template <chip CHIP>
VKAPI_ATTR void VKAPI_CALL VKAPI_ATTR void VKAPI_CALL
tu_CmdNextSubpass2(VkCommandBuffer commandBuffer, tu_CmdNextSubpass2(VkCommandBuffer commandBuffer,

View file

@ -2895,12 +2895,14 @@ static const enum mesa_vk_dynamic_graphics_state tu_blend_state[] = {
MESA_VK_DYNAMIC_MS_ALPHA_TO_COVERAGE_ENABLE, MESA_VK_DYNAMIC_MS_ALPHA_TO_COVERAGE_ENABLE,
MESA_VK_DYNAMIC_MS_ALPHA_TO_ONE_ENABLE, MESA_VK_DYNAMIC_MS_ALPHA_TO_ONE_ENABLE,
MESA_VK_DYNAMIC_MS_SAMPLE_MASK, MESA_VK_DYNAMIC_MS_SAMPLE_MASK,
MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP,
}; };
template <chip CHIP> template <chip CHIP>
static unsigned static unsigned
tu6_blend_size(struct tu_device *dev, tu6_blend_size(struct tu_device *dev,
const struct vk_color_blend_state *cb, const struct vk_color_blend_state *cb,
const struct vk_color_attachment_location_state *cal,
bool alpha_to_coverage_enable, bool alpha_to_coverage_enable,
bool alpha_to_one_enable, bool alpha_to_one_enable,
uint32_t sample_mask) uint32_t sample_mask)
@ -2914,6 +2916,7 @@ template <chip CHIP>
static void static void
tu6_emit_blend(struct tu_cs *cs, tu6_emit_blend(struct tu_cs *cs,
const struct vk_color_blend_state *cb, const struct vk_color_blend_state *cb,
const struct vk_color_attachment_location_state *cal,
bool alpha_to_coverage_enable, bool alpha_to_coverage_enable,
bool alpha_to_one_enable, bool alpha_to_one_enable,
uint32_t sample_mask) uint32_t sample_mask)
@ -2923,12 +2926,14 @@ tu6_emit_blend(struct tu_cs *cs,
uint32_t blend_enable_mask = 0; uint32_t blend_enable_mask = 0;
for (unsigned i = 0; i < cb->attachment_count; i++) { for (unsigned i = 0; i < cb->attachment_count; i++) {
const struct vk_color_blend_attachment_state *att = &cb->attachments[i]; if (!(cb->color_write_enables & (1u << i)) ||
if (!(cb->color_write_enables & (1u << i))) cal->color_map[i] == MESA_VK_ATTACHMENT_UNUSED)
continue; continue;
const struct vk_color_blend_attachment_state *att = &cb->attachments[i];
if (rop_reads_dst || att->blend_enable) { if (rop_reads_dst || att->blend_enable) {
blend_enable_mask |= 1u << i; blend_enable_mask |= 1u << cal->color_map[i];
} }
} }
@ -2960,6 +2965,9 @@ tu6_emit_blend(struct tu_cs *cs,
.sample_mask = sample_mask)); .sample_mask = sample_mask));
for (unsigned i = 0; i < num_rts; i++) { for (unsigned i = 0; i < num_rts; i++) {
if (cal->color_map[i] == MESA_VK_ATTACHMENT_UNUSED)
continue;
unsigned remapped_idx = cal->color_map[i];
const struct vk_color_blend_attachment_state *att = &cb->attachments[i]; const struct vk_color_blend_attachment_state *att = &cb->attachments[i];
if ((cb->color_write_enables & (1u << i)) && i < cb->attachment_count) { if ((cb->color_write_enables & (1u << i)) && i < cb->attachment_count) {
const enum a3xx_rb_blend_opcode color_op = tu6_blend_op(att->color_blend_op); const enum a3xx_rb_blend_opcode color_op = tu6_blend_op(att->color_blend_op);
@ -2975,13 +2983,13 @@ tu6_emit_blend(struct tu_cs *cs,
tu6_blend_factor((VkBlendFactor)att->dst_alpha_blend_factor); tu6_blend_factor((VkBlendFactor)att->dst_alpha_blend_factor);
tu_cs_emit_regs(cs, tu_cs_emit_regs(cs,
A6XX_RB_MRT_CONTROL(i, A6XX_RB_MRT_CONTROL(remapped_idx,
.blend = att->blend_enable, .blend = att->blend_enable,
.blend2 = att->blend_enable, .blend2 = att->blend_enable,
.rop_enable = cb->logic_op_enable, .rop_enable = cb->logic_op_enable,
.rop_code = rop, .rop_code = rop,
.component_enable = att->write_mask), .component_enable = att->write_mask),
A6XX_RB_MRT_BLEND_CONTROL(i, A6XX_RB_MRT_BLEND_CONTROL(remapped_idx,
.rgb_src_factor = src_color_factor, .rgb_src_factor = src_color_factor,
.rgb_blend_opcode = color_op, .rgb_blend_opcode = color_op,
.rgb_dest_factor = dst_color_factor, .rgb_dest_factor = dst_color_factor,
@ -2990,8 +2998,8 @@ tu6_emit_blend(struct tu_cs *cs,
.alpha_dest_factor = dst_alpha_factor)); .alpha_dest_factor = dst_alpha_factor));
} else { } else {
tu_cs_emit_regs(cs, tu_cs_emit_regs(cs,
A6XX_RB_MRT_CONTROL(i,), A6XX_RB_MRT_CONTROL(remapped_idx,),
A6XX_RB_MRT_BLEND_CONTROL(i,)); A6XX_RB_MRT_BLEND_CONTROL(remapped_idx,));
} }
} }
} }
@ -3394,6 +3402,7 @@ tu_pipeline_builder_emit_state(struct tu_pipeline_builder *builder,
BITSET_SET(pipeline_set, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS); BITSET_SET(pipeline_set, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS);
} }
DRAW_STATE(blend, TU_DYNAMIC_STATE_BLEND, cb, DRAW_STATE(blend, TU_DYNAMIC_STATE_BLEND, cb,
builder->graphics_state.cal,
builder->graphics_state.ms->alpha_to_coverage_enable, builder->graphics_state.ms->alpha_to_coverage_enable,
builder->graphics_state.ms->alpha_to_one_enable, builder->graphics_state.ms->alpha_to_one_enable,
builder->graphics_state.ms->sample_mask); builder->graphics_state.ms->sample_mask);
@ -3607,6 +3616,7 @@ tu_emit_draw_state(struct tu_cmd_buffer *cmd)
&cmd->vk.dynamic_graphics_state.rs); &cmd->vk.dynamic_graphics_state.rs);
DRAW_STATE(blend, TU_DYNAMIC_STATE_BLEND, DRAW_STATE(blend, TU_DYNAMIC_STATE_BLEND,
&cmd->vk.dynamic_graphics_state.cb, &cmd->vk.dynamic_graphics_state.cb,
&cmd->vk.dynamic_graphics_state.cal,
cmd->vk.dynamic_graphics_state.ms.alpha_to_coverage_enable, cmd->vk.dynamic_graphics_state.ms.alpha_to_coverage_enable,
cmd->vk.dynamic_graphics_state.ms.alpha_to_one_enable, cmd->vk.dynamic_graphics_state.ms.alpha_to_one_enable,
cmd->vk.dynamic_graphics_state.ms.sample_mask); cmd->vk.dynamic_graphics_state.ms.sample_mask);