Merge branch 'vulkan/subpass-merge' into 'main'

Draft: vulkan,panvk: Merge subpasses

See merge request mesa/mesa!38889
This commit is contained in:
Faith Ekstrand 2025-12-20 00:51:09 +00:00
commit a2ee14ba9e
16 changed files with 2009 additions and 700 deletions

View file

@ -142,6 +142,21 @@ emit_clear_rects(struct nvk_cmd_buffer *cmd,
}
}
static uint32_t
get_color_target_index(const struct vk_dynamic_graphics_state *dyn,
uint32_t attachment)
{
if (attachment == VK_ATTACHMENT_UNUSED)
return VK_ATTACHMENT_UNUSED;
for (uint8_t a = 0; a < MESA_VK_MAX_COLOR_ATTACHMENTS; a++) {
if (dyn->rp.color_attachment_remap[a] == attachment)
return a;
}
return VK_ATTACHMENT_UNUSED;
}
VKAPI_ATTR void VKAPI_CALL
nvk_CmdClearAttachments(VkCommandBuffer commandBuffer,
uint32_t attachmentCount,
@ -189,7 +204,9 @@ nvk_CmdClearAttachments(VkCommandBuffer commandBuffer,
if (pAttachments[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT)
continue;
if (pAttachments[i].colorAttachment == VK_ATTACHMENT_UNUSED)
const uint32_t ct =
get_color_target_index(dyn, pAttachments[i].colorAttachment);
if (ct == VK_ATTACHMENT_UNUSED)
continue;
VkClearColorValue color = pAttachments[i].clearValue.color;
@ -201,8 +218,7 @@ nvk_CmdClearAttachments(VkCommandBuffer commandBuffer,
P_NV9097_SET_COLOR_CLEAR_VALUE(p, 2, color.uint32[2]);
P_NV9097_SET_COLOR_CLEAR_VALUE(p, 3, color.uint32[3]);
emit_clear_rects(cmd, pAttachments[i].colorAttachment,
clear_depth, clear_stencil, rectCount, pRects);
emit_clear_rects(cmd, ct, clear_depth, clear_stencil, rectCount, pRects);
/* We only need to clear depth/stencil once */
clear_depth = clear_stencil = false;

View file

@ -749,6 +749,11 @@ nvk_cmd_buffer_begin_graphics(struct nvk_cmd_buffer *cmd,
render->stencil_att.vk_format =
inheritance_info->stencilAttachmentFormat;
const VkRenderingAttachmentRemapInfoMESA *rar_info =
vk_find_struct_const(inheritance_info->pNext,
RENDERING_ATTACHMENT_REMAP_INFO_MESA);
vk_cmd_set_rendering_attachment_remap(&cmd->vk, rar_info);
const VkRenderingAttachmentLocationInfoKHR att_loc_info_default = {
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_LOCATION_INFO_KHR,
.colorAttachmentCount = inheritance_info->colorAttachmentCount,
@ -1404,8 +1409,17 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer,
if (sample_layout != NIL_SAMPLE_LAYOUT_INVALID)
nvk_cmd_set_sample_layout(cmd, sample_layout);
if (render->flags & VK_RENDERING_RESUMING_BIT)
const VkRenderingAttachmentRemapInfoMESA *rar_info =
vk_find_struct_const(pRenderingInfo->pNext,
RENDERING_ATTACHMENT_REMAP_INFO_MESA);
if (render->flags & VK_RENDERING_RESUMING_BIT) {
vk_cmd_set_rendering_attachment_remap(&cmd->vk, rar_info);
return;
}
/* We don't want a previous remap messing up our clears */
vk_cmd_set_rendering_attachment_remap(&cmd->vk, NULL);
for (uint32_t i = 0; i < pRenderingInfo->colorAttachmentCount; i++) {
const struct nvk_image_view *iview = render->color_att[i].iview;
@ -1477,7 +1491,11 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer,
P_NV9097_SET_RENDER_ENABLE_OVERRIDE(p, MODE_USE_RENDER_ENABLE);
}
/* TODO: Attachment clears */
/* This needs to be set after the clears because the clears that are part
* of CmdBeginRendering() apply to the entire render, not just the
* attachments selected by the remap.
*/
vk_cmd_set_rendering_attachment_remap(&cmd->vk, rar_info);
}
VKAPI_ATTR void VKAPI_CALL
@ -3179,14 +3197,18 @@ nvk_flush_ds_state(struct nvk_cmd_buffer *cmd)
const struct vk_dynamic_graphics_state *dyn =
&cmd->vk.dynamic_graphics_state;
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE)) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_TEST_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RP_REMAP)) {
bool enable = dyn->ds.depth.test_enable &&
dyn->rp.depth_stencil_attachment_enable &&
render->depth_att.vk_format != VK_FORMAT_UNDEFINED;
P_IMMD(p, NV9097, SET_DEPTH_TEST, enable);
}
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE)) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RP_REMAP)) {
bool enable = dyn->ds.depth.write_enable &&
dyn->rp.depth_stencil_attachment_enable &&
render->depth_att.vk_format != VK_FORMAT_UNDEFINED;
P_IMMD(p, NV9097, SET_DEPTH_WRITE, enable);
}
@ -3208,8 +3230,10 @@ nvk_flush_ds_state(struct nvk_cmd_buffer *cmd)
P_NV9097_SET_DEPTH_BOUNDS_MAX(p, fui(dyn->ds.depth.bounds_test.max));
}
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE)) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RP_REMAP)) {
bool enable = dyn->ds.stencil.test_enable &&
dyn->rp.depth_stencil_attachment_enable &&
render->stencil_att.vk_format != VK_FORMAT_UNDEFINED;
P_IMMD(p, NV9097, SET_STENCIL_TEST, enable);
}
@ -3376,6 +3400,33 @@ nvk_mme_set_write_mask(struct mme_builder *b)
mme_emit(b, common_mask);
}
static const struct vk_color_blend_attachment_state *
get_blend_attachment_state(const struct vk_dynamic_graphics_state *dyn,
uint32_t a)
{
uint32_t remap = dyn->rp.color_attachment_remap[a];
return remap == MESA_VK_ATTACHMENT_UNUSED ?
NULL : &dyn->cb.attachments[remap];
}
static bool
get_color_write_enabled(const struct vk_dynamic_graphics_state *dyn,
uint32_t a)
{
uint32_t remap = dyn->rp.color_attachment_remap[a];
return remap == MESA_VK_ATTACHMENT_UNUSED ?
false : (dyn->cb.color_write_enables & BITFIELD_BIT(remap));
}
static uint8_t
get_color_attachment_location(const struct vk_dynamic_graphics_state *dyn,
uint32_t a)
{
uint32_t remap = dyn->rp.color_attachment_remap[a];
return remap == MESA_VK_ATTACHMENT_UNUSED ?
MESA_VK_ATTACHMENT_UNUSED : dyn->cal.color_map[remap];
}
static void
nvk_flush_cb_state(struct nvk_cmd_buffer *cmd)
{
@ -3394,16 +3445,23 @@ nvk_flush_cb_state(struct nvk_cmd_buffer *cmd)
P_IMMD(p, NV9097, SET_LOGIC_OP_FUNC, func);
}
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_BLEND_ENABLES)) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_BLEND_ENABLES) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RP_REMAP)) {
for (uint8_t a = 0; a < render->color_att_count; a++) {
P_IMMD(p, NV9097, SET_BLEND(a), dyn->cb.attachments[a].blend_enable);
const struct vk_color_blend_attachment_state *att =
get_blend_attachment_state(dyn, a);
P_IMMD(p, NV9097, SET_BLEND(a), att != NULL && att->blend_enable);
}
}
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS)) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_BLEND_EQUATIONS) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RP_REMAP)) {
for (uint8_t a = 0; a < render->color_att_count; a++) {
const struct vk_color_blend_attachment_state *att =
&dyn->cb.attachments[a];
get_blend_attachment_state(dyn, a);
if (att == NULL)
continue;
P_MTHD(p, NV9097, SET_BLEND_PER_TARGET_SEPARATE_FOR_ALPHA(a));
P_NV9097_SET_BLEND_PER_TARGET_SEPARATE_FOR_ALPHA(p, a, ENABLE_TRUE);
P_NV9097_SET_BLEND_PER_TARGET_COLOR_OP(p, a,
@ -3424,26 +3482,31 @@ nvk_flush_cb_state(struct nvk_cmd_buffer *cmd)
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_WRITE_MASKS) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_CB_COLOR_WRITE_ENABLES) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RP_ATTACHMENTS) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RP_REMAP) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP)) {
uint32_t color_write_enables = 0x0;
for (uint8_t a = 0; a < render->color_att_count; a++) {
if (dyn->cb.color_write_enables & BITFIELD_BIT(a))
if (get_color_write_enabled(dyn, a))
color_write_enables |= 0xf << (4 * a);
}
uint32_t cb_att_write_mask = 0x0;
for (uint8_t a = 0; a < render->color_att_count; a++)
cb_att_write_mask |= dyn->cb.attachments[a].write_mask << (a * 4);
for (uint8_t a = 0; a < render->color_att_count; a++) {
const struct vk_color_blend_attachment_state *att =
get_blend_attachment_state(dyn, a);
cb_att_write_mask |= (att != NULL ? att->write_mask : 0) << (a * 4);
}
uint32_t rp_att_write_mask = 0x0;
for (uint8_t a = 0; a < MESA_VK_MAX_COLOR_ATTACHMENTS; a++) {
if (dyn->rp.attachments & (MESA_VK_RP_ATTACHMENT_COLOR_0_BIT << a))
if (dyn->rp.attachments & MESA_VK_RP_ATTACHMENT_COLOR_BIT(a))
rp_att_write_mask |= 0xf << (4 * a);
}
uint32_t att_has_loc_mask = 0x0;
for (uint8_t a = 0; a < MESA_VK_MAX_COLOR_ATTACHMENTS; a++) {
if (dyn->cal.color_map[a] != MESA_VK_ATTACHMENT_UNUSED)
uint8_t loc = get_color_attachment_location(dyn, a);
if (loc != MESA_VK_ATTACHMENT_UNUSED)
att_has_loc_mask |= 0xf << (4 * a);
}
@ -3455,19 +3518,22 @@ nvk_flush_cb_state(struct nvk_cmd_buffer *cmd)
att_has_loc_mask);
}
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP)) {
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RP_ATTACHMENTS) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RP_REMAP) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP)) {
int8_t loc_att[NVK_MAX_RTS] = { -1, -1, -1, -1, -1, -1, -1, -1};
uint8_t max_loc = 0;
uint32_t att_used = 0;
for (uint8_t a = 0; a < render->color_att_count; a++) {
if (dyn->cal.color_map[a] == MESA_VK_ATTACHMENT_UNUSED)
uint8_t loc = get_color_attachment_location(dyn, a);
if (loc == MESA_VK_ATTACHMENT_UNUSED)
continue;
att_used |= BITFIELD_BIT(a);
assert(dyn->cal.color_map[a] < NVK_MAX_RTS);
loc_att[dyn->cal.color_map[a]] = a;
max_loc = MAX2(max_loc, dyn->cal.color_map[a]);
assert(loc < NVK_MAX_RTS);
loc_att[loc] = a;
max_loc = MAX2(max_loc, loc);
}
for (uint8_t l = 0; l < NVK_MAX_RTS; l++) {

View file

@ -918,7 +918,12 @@ pan_emit_rt(const struct pan_fb_info *fb, unsigned layer_idx, unsigned idx,
cfg.internal_buffer_offset = cbuf_offset;
cfg.clear = rt_clear(&fb->rts[idx]);
cfg.dithering_enable = true;
cfg.internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_R8G8B8A8;
if (rt) {
get_rt_formats(rt->format, &cfg.writeback_format,
&cfg.internal_format, &cfg.swizzle);
} else {
cfg.internal_format = MALI_COLOR_BUFFER_INTERNAL_FORMAT_R8G8B8A8;
}
#if PAN_ARCH >= 7
cfg.writeback_block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED;
#endif

View file

@ -455,6 +455,8 @@ prepare_fs_driver_set(struct panvk_cmd_buffer *cmdbuf)
static bool
has_depth_att(struct panvk_cmd_buffer *cmdbuf)
{
if (!cmdbuf->vk.dynamic_graphics_state.rp.depth_stencil_attachment_enable)
return false;
return (cmdbuf->state.gfx.render.bound_attachments &
MESA_VK_RP_ATTACHMENT_DEPTH_BIT) != 0;
}
@ -462,6 +464,8 @@ has_depth_att(struct panvk_cmd_buffer *cmdbuf)
static bool
has_stencil_att(struct panvk_cmd_buffer *cmdbuf)
{
if (!cmdbuf->vk.dynamic_graphics_state.rp.depth_stencil_attachment_enable)
return false;
return (cmdbuf->state.gfx.render.bound_attachments &
MESA_VK_RP_ATTACHMENT_STENCIL_BIT) != 0;
}
@ -653,6 +657,7 @@ prepare_blend(struct panvk_cmd_buffer *cmdbuf)
dyn_gfx_state_dirty(cmdbuf, CB_BLEND_EQUATIONS) ||
dyn_gfx_state_dirty(cmdbuf, CB_WRITE_MASKS) ||
dyn_gfx_state_dirty(cmdbuf, CB_BLEND_CONSTANTS) ||
dyn_gfx_state_dirty(cmdbuf, RP_REMAP) ||
dyn_gfx_state_dirty(cmdbuf, COLOR_ATTACHMENT_MAP) ||
fs_user_dirty(cmdbuf) || gfx_state_dirty(cmdbuf, RENDER_STATE);
@ -1799,6 +1804,7 @@ prepare_ds(struct panvk_cmd_buffer *cmdbuf, struct pan_earlyzs_state earlyzs)
dyn_gfx_state_dirty(cmdbuf, RS_DEPTH_BIAS_ENABLE) ||
dyn_gfx_state_dirty(cmdbuf, RS_DEPTH_BIAS_FACTORS) ||
dyn_gfx_state_dirty(cmdbuf, MS_ALPHA_TO_COVERAGE_ENABLE) ||
dyn_gfx_state_dirty(cmdbuf, RP_REMAP) ||
dyn_gfx_state_dirty(cmdbuf, INPUT_ATTACHMENT_MAP) ||
fs_user_dirty(cmdbuf) || gfx_state_dirty(cmdbuf, OQ);
@ -1960,6 +1966,7 @@ prepare_dcd(struct panvk_cmd_buffer *cmdbuf,
dyn_gfx_state_dirty(cmdbuf, MS_SAMPLE_MASK) ||
dyn_gfx_state_dirty(cmdbuf, MS_ALPHA_TO_COVERAGE_ENABLE) ||
dyn_gfx_state_dirty(cmdbuf, MS_ALPHA_TO_ONE_ENABLE) ||
dyn_gfx_state_dirty(cmdbuf, RP_REMAP) ||
/* writes_depth() uses vk_depth_stencil_state */
dyn_gfx_state_dirty(cmdbuf, DS_DEPTH_TEST_ENABLE) ||
dyn_gfx_state_dirty(cmdbuf, DS_DEPTH_WRITE_ENABLE) ||
@ -2915,6 +2922,11 @@ panvk_per_arch(cmd_inherit_render_state)(
att_loc_info = &att_loc_info_default;
vk_cmd_set_rendering_attachment_locations(&cmdbuf->vk, att_loc_info);
const VkRenderingAttachmentRemapInfoMESA *rar_info =
vk_find_struct_const(inheritance_info->pNext,
RENDERING_ATTACHMENT_REMAP_INFO_MESA);
vk_cmd_set_rendering_attachment_remap(&cmdbuf->vk, rar_info);
}
VKAPI_ATTR void VKAPI_CALL

View file

@ -92,6 +92,8 @@ is_indirect_draw(const struct panvk_draw_data *draw)
static bool
has_depth_att(struct panvk_cmd_buffer *cmdbuf)
{
if (!cmdbuf->vk.dynamic_graphics_state.rp.depth_stencil_attachment_enable)
return false;
return (cmdbuf->state.gfx.render.bound_attachments &
MESA_VK_RP_ATTACHMENT_DEPTH_BIT) != 0;
}
@ -99,6 +101,8 @@ has_depth_att(struct panvk_cmd_buffer *cmdbuf)
static bool
has_stencil_att(struct panvk_cmd_buffer *cmdbuf)
{
if (!cmdbuf->vk.dynamic_graphics_state.rp.depth_stencil_attachment_enable)
return false;
return (cmdbuf->state.gfx.render.bound_attachments &
MESA_VK_RP_ATTACHMENT_STENCIL_BIT) != 0;
}
@ -225,6 +229,7 @@ panvk_draw_prepare_fs_rsd(struct panvk_cmd_buffer *cmdbuf,
dyn_gfx_state_dirty(cmdbuf, MS_SAMPLE_MASK) ||
dyn_gfx_state_dirty(cmdbuf, MS_ALPHA_TO_COVERAGE_ENABLE) ||
dyn_gfx_state_dirty(cmdbuf, MS_ALPHA_TO_ONE_ENABLE) ||
dyn_gfx_state_dirty(cmdbuf, RP_REMAP) ||
gfx_state_dirty(cmdbuf, FS) || gfx_state_dirty(cmdbuf, OQ) ||
gfx_state_dirty(cmdbuf, RENDER_STATE);

View file

@ -326,7 +326,7 @@ panvk_per_arch(blend_emit_descs)(struct panvk_cmd_buffer *cmdbuf,
uint64_t blend_shaders[8] = {};
/* All bits set to one encodes unused fixed-function blend constant. */
unsigned ff_blend_constant = ~0;
uint8_t remap_catts[MAX_RTS] = {
uint8_t loc_rt[MAX_RTS] = {
MESA_VK_ATTACHMENT_UNUSED, MESA_VK_ATTACHMENT_UNUSED,
MESA_VK_ATTACHMENT_UNUSED, MESA_VK_ATTACHMENT_UNUSED,
MESA_VK_ATTACHMENT_UNUSED, MESA_VK_ATTACHMENT_UNUSED,
@ -334,41 +334,50 @@ panvk_per_arch(blend_emit_descs)(struct panvk_cmd_buffer *cmdbuf,
};
uint32_t blend_count = MAX2(cmdbuf->state.gfx.render.fb.info.rt_count, 1);
static_assert(ARRAY_SIZE(remap_catts) <= ARRAY_SIZE(cal->color_map),
"vk_color_attachment_location_state::color_map is too small");
for (uint32_t i = 0; i < ARRAY_SIZE(remap_catts); i++) {
if (cal->color_map[i] != MESA_VK_ATTACHMENT_UNUSED) {
assert(cal->color_map[i] < MAX_RTS);
remap_catts[cal->color_map[i]] = i;
}
}
memset(blend_info, 0, sizeof(*blend_info));
for (uint8_t i = 0; i < cb->attachment_count; i++) {
struct pan_blend_rt_state *rt = &bs.rts[i];
if (cal->color_map[i] == MESA_VK_ATTACHMENT_UNUSED) {
for (uint8_t rt_idx = 0; rt_idx < MAX_RTS; rt_idx++) {
struct pan_blend_rt_state *rt = &bs.rts[rt_idx];
/* This is the API-level attachment for things other than the bound
* render targets. In particular, we use this index for blend
* attachments and color write enables.
*/
const uint8_t att = dyns->rp.color_attachment_remap[rt_idx];
if (att == MESA_VK_ATTACHMENT_UNUSED) {
rt->equation.color_mask = 0;
continue;
}
assert(att < MAX_RTS);
/* This is the location inside the shader where this color attachment
* will be bound.
*/
const uint8_t loc = cal->color_map[rt_idx];
if (loc == MESA_VK_ATTACHMENT_UNUSED) {
rt->equation.color_mask = 0;
continue;
}
assert(loc < MAX_RTS);
loc_rt[loc] = rt_idx;
if (!(cb->color_write_enables & BITFIELD_BIT(att))) {
rt->equation.color_mask = 0;
continue;
}
if (!(cb->color_write_enables & BITFIELD_BIT(i))) {
if (color_attachment_formats[rt_idx] == VK_FORMAT_UNDEFINED) {
rt->equation.color_mask = 0;
continue;
}
if (color_attachment_formats[i] == VK_FORMAT_UNDEFINED) {
if (!cb->attachments[att].write_mask) {
rt->equation.color_mask = 0;
continue;
}
if (!cb->attachments[i].write_mask) {
rt->equation.color_mask = 0;
continue;
}
rt->format = vk_format_to_pipe_format(color_attachment_formats[i]);
rt->format = vk_format_to_pipe_format(color_attachment_formats[rt_idx]);
rt->nr_samples = color_attachment_samples[rt_idx];
/* Disable blending for LOGICOP_NOOP unless the format is float/srgb */
if (bs.logicop_enable && bs.logicop_func == PIPE_LOGICOP_NOOP &&
@ -378,21 +387,20 @@ panvk_per_arch(blend_emit_descs)(struct panvk_cmd_buffer *cmdbuf,
continue;
}
rt->nr_samples = color_attachment_samples[i];
rt->equation.blend_enable = cb->attachments[i].blend_enable;
rt->equation.color_mask = cb->attachments[i].write_mask;
rt->equation.blend_enable = cb->attachments[att].blend_enable;
rt->equation.color_mask = cb->attachments[att].write_mask;
rt->equation.rgb_func =
vk_blend_op_to_pipe(cb->attachments[i].color_blend_op);
vk_blend_op_to_pipe(cb->attachments[att].color_blend_op);
rt->equation.rgb_src_factor =
vk_blend_factor_to_pipe(cb->attachments[i].src_color_blend_factor);
vk_blend_factor_to_pipe(cb->attachments[att].src_color_blend_factor);
rt->equation.rgb_dst_factor =
vk_blend_factor_to_pipe(cb->attachments[i].dst_color_blend_factor);
vk_blend_factor_to_pipe(cb->attachments[att].dst_color_blend_factor);
rt->equation.alpha_func =
vk_blend_op_to_pipe(cb->attachments[i].alpha_blend_op);
vk_blend_op_to_pipe(cb->attachments[att].alpha_blend_op);
rt->equation.alpha_src_factor =
vk_blend_factor_to_pipe(cb->attachments[i].src_alpha_blend_factor);
vk_blend_factor_to_pipe(cb->attachments[att].src_alpha_blend_factor);
rt->equation.alpha_dst_factor =
vk_blend_factor_to_pipe(cb->attachments[i].dst_alpha_blend_factor);
vk_blend_factor_to_pipe(cb->attachments[att].dst_alpha_blend_factor);
bool dest_has_alpha = util_format_has_alpha(rt->format);
if (!dest_has_alpha) {
@ -409,12 +417,12 @@ panvk_per_arch(blend_emit_descs)(struct panvk_cmd_buffer *cmdbuf,
blend_info->any_dest_read |= pan_blend_reads_dest(rt->equation);
if (blend_needs_shader(&bs, i, &ff_blend_constant)) {
nir_alu_type src0_type = fs_info->bifrost.blend[i].type;
if (blend_needs_shader(&bs, rt_idx, &ff_blend_constant)) {
nir_alu_type src0_type = fs_info->bifrost.blend[loc].type;
nir_alu_type src1_type = fs_info->bifrost.blend_src1_type;
VkResult result = get_blend_shader(dev, &bs, src0_type, src1_type,
i, &blend_shaders[i]);
rt_idx, &blend_shaders[rt_idx]);
if (result != VK_SUCCESS)
return result;
@ -429,13 +437,13 @@ panvk_per_arch(blend_emit_descs)(struct panvk_cmd_buffer *cmdbuf,
ff_blend_constant = 0;
/* Now that we've collected all the information, we can emit. */
for (uint8_t i = 0; i < blend_count; i++) {
uint32_t catt_idx = remap_catts[i];
for (uint8_t loc = 0; loc < blend_count; loc++) {
uint32_t rt_idx = loc_rt[loc];
uint64_t blend_shader =
catt_idx != MESA_VK_ATTACHMENT_UNUSED ? blend_shaders[catt_idx] : 0;
rt_idx != MESA_VK_ATTACHMENT_UNUSED ? blend_shaders[rt_idx] : 0;
emit_blend_desc(fs_info, fs_code, &bs, i, catt_idx,
blend_shader, ff_blend_constant, &bds[i]);
emit_blend_desc(fs_info, fs_code, &bs, loc, rt_idx,
blend_shader, ff_blend_constant, &bds[loc]);
}
if (blend_info->shader_loads_blend_const)

View file

@ -463,6 +463,11 @@ panvk_per_arch(cmd_init_render_state)(struct panvk_cmd_buffer *cmdbuf,
}
assert(fbinfo->width && fbinfo->height);
const VkRenderingAttachmentRemapInfoMESA *rar_info =
vk_find_struct_const(pRenderingInfo->pNext,
RENDERING_ATTACHMENT_REMAP_INFO_MESA);
vk_cmd_set_rendering_attachment_remap(&cmdbuf->vk, rar_info);
}
void

View file

@ -235,6 +235,8 @@ panvk_per_arch(CmdClearAttachments)(VkCommandBuffer commandBuffer,
const VkClearRect *pRects)
{
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer);
const struct vk_dynamic_graphics_state *dyns =
&cmdbuf->vk.dynamic_graphics_state;
struct panvk_device *dev = to_panvk_device(cmdbuf->vk.base.device);
struct panvk_cmd_meta_graphics_save_ctx save = {0};
struct vk_meta_rendering_info render = {
@ -252,9 +254,36 @@ panvk_per_arch(CmdClearAttachments)(VkCommandBuffer commandBuffer,
VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
}
STACK_ARRAY(VkClearAttachment, attachments, attachmentCount);
uint32_t attachment_count = 0;
for (uint32_t i = 0; i < attachmentCount; i++) {
if (pAttachments[i].aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT |
VK_IMAGE_ASPECT_STENCIL_BIT)) {
attachments[attachment_count++] = pAttachments[i];
continue;
}
uint32_t rt;
for (rt = 0; rt < MAX_RTS; rt++) {
if (dyns->rp.color_attachment_remap[rt] ==
pAttachments[i].colorAttachment)
break;
}
if (rt == MAX_RTS)
continue;
attachments[attachment_count++] = (VkClearAttachment) {
.aspectMask = pAttachments[i].aspectMask,
.colorAttachment = rt,
.clearValue = pAttachments[i].clearValue,
};
}
panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
vk_meta_clear_attachments(&cmdbuf->vk, &dev->meta, &render, attachmentCount,
pAttachments, rectCount, pRects);
vk_meta_clear_attachments(&cmdbuf->vk, &dev->meta, &render,
attachment_count, attachments,
rectCount, pRects);
panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save);
}

View file

@ -488,6 +488,10 @@ panvk_hash_state(struct vk_physical_device *device,
_mesa_blake3_update(&blake3_ctx, &state->rp->view_mask,
sizeof(state->rp->view_mask));
if (state->rp)
_mesa_blake3_update(&blake3_ctx, state->rp->color_attachment_remap,
sizeof(state->rp->color_attachment_remap));
if (state->ial)
_mesa_blake3_update(&blake3_ctx, state->ial, sizeof(*state->ial));
}
@ -1373,6 +1377,29 @@ panvk_compile_shader(struct panvk_device *dev,
if (state && state->ms && state->ms->sample_shading_enable)
nir->info.fs.uses_sample_shading = true;
bool demoted_output = false;
nir_foreach_shader_out_variable(var, nir) {
if (var->data.location < FRAG_RESULT_DATA0)
continue;
uint32_t loc = var->data.location - FRAG_RESULT_DATA0;
uint32_t rt;
for (rt = 0; rt < MAX_RTS; rt++) {
if (state->rp->color_attachment_remap[rt] == loc)
break;
}
if (rt < MAX_RTS) {
var->data.location = FRAG_RESULT_DATA0 + rt;
} else {
var->data.mode = nir_var_shader_temp;
demoted_output = true;
}
}
if (demoted_output) {
NIR_PASS(_, nir, nir_fixup_deref_modes);
NIR_PASS(_, nir, nir_lower_global_vars_to_local);
}
/* We need to lower input attachments before we lower descriptors */
NIR_PASS(_, nir, panvk_per_arch(nir_lower_input_attachment_loads),
state, &variant->fs.input_attachment_read);

View file

@ -1303,6 +1303,17 @@ vk_render_pass_state_init(struct vk_render_pass_state *rp,
rp->depth_stencil_attachment_samples = asc_info->depthStencilAttachmentSamples;
}
const VkRenderingAttachmentRemapInfoMESA *rar_info =
!driver_rp ? vk_get_pipeline_rendering_ar_info(info) : NULL;
for (uint32_t i = 0; i < MESA_VK_MAX_COLOR_ATTACHMENTS; i++) {
rp->color_attachment_remap[i] =
rar_info == NULL ? i :
rar_info->colorAttachmentRemap[i] == VK_ATTACHMENT_UNUSED ?
MESA_VK_ATTACHMENT_UNUSED : rar_info->colorAttachmentRemap[i];
}
rp->depth_stencil_attachment_enable =
rar_info == NULL || rar_info->depthStencilAttachmentEnable;
for (uint32_t i = 0; i < r_info->colorAttachmentCount; i++) {
if (rp->color_attachment_formats[i] != VK_FORMAT_UNDEFINED)
rp->attachments |= MESA_VK_RP_ATTACHMENT_COLOR_BIT(i);
@ -1320,6 +1331,14 @@ vk_dynamic_graphics_state_init_rp(struct vk_dynamic_graphics_state *dst,
const struct vk_render_pass_state *rp)
{
dst->rp.attachments = rp->attachments;
STATIC_ASSERT(sizeof(dst->rp.color_attachment_remap) ==
sizeof(rp->color_attachment_remap));
memcpy(dst->rp.color_attachment_remap, rp->color_attachment_remap,
sizeof(rp->color_attachment_remap));
dst->rp.depth_stencil_attachment_enable =
rp->depth_stencil_attachment_enable;
}
#define FOREACH_STATE_GROUP(f) \
@ -2264,6 +2283,11 @@ vk_dynamic_graphics_state_copy(struct vk_dynamic_graphics_state *dst,
COPY_ARRAY(CB_BLEND_CONSTANTS, cb.blend_constants, 4);
COPY_IF_SET(RP_ATTACHMENTS, rp.attachments);
if (IS_SET_IN_SRC(RP_REMAP)) {
COPY_ARRAY(RP_REMAP, rp.color_attachment_remap,
MESA_VK_MAX_COLOR_ATTACHMENTS);
COPY_MEMBER(RP_REMAP, rp.attachments);
}
if (IS_SET_IN_SRC(INPUT_ATTACHMENT_MAP)) {
COPY_MEMBER(INPUT_ATTACHMENT_MAP, ial.color_attachment_count);
@ -3191,6 +3215,23 @@ vk_common_CmdSetRenderingAttachmentLocationsKHR(
vk_cmd_set_rendering_attachment_locations(cmd, pLocationInfo);
}
void
vk_cmd_set_rendering_attachment_remap(struct vk_command_buffer *cmd,
const VkRenderingAttachmentRemapInfoMESA *info)
{
struct vk_dynamic_graphics_state *dyn = &cmd->dynamic_graphics_state;
for (uint32_t i = 0; i < MESA_VK_MAX_COLOR_ATTACHMENTS; i++) {
const uint8_t remap =
info == NULL ? i :
info->colorAttachmentRemap[i] == VK_ATTACHMENT_UNUSED ?
MESA_VK_ATTACHMENT_UNUSED : info->colorAttachmentRemap[i];
SET_DYN_VALUE(dyn, RP_REMAP, rp.color_attachment_remap[i], remap);
}
SET_DYN_VALUE(dyn, RP_REMAP, rp.depth_stencil_attachment_enable,
info == NULL || info->depthStencilAttachmentEnable);
}
VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetRenderingInputAttachmentIndicesKHR(
VkCommandBuffer commandBuffer,

View file

@ -27,6 +27,7 @@
#include "vulkan/vulkan_core.h"
#include "vk_limits.h"
#include "vk_internal_exts.h"
#include "util/bitset.h"
#include "util/enum_operators.h"
@ -105,6 +106,7 @@ enum mesa_vk_dynamic_graphics_state {
MESA_VK_DYNAMIC_CB_WRITE_MASKS,
MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS,
MESA_VK_DYNAMIC_RP_ATTACHMENTS,
MESA_VK_DYNAMIC_RP_REMAP,
MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE,
MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP,
MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP,
@ -768,6 +770,10 @@ struct vk_color_attachment_location_state {
/***/
struct vk_render_pass_state {
/** Set of image aspects bound as color/depth/stencil attachments
*
* If VkRenderingDepthStencilOutputEnableInfoMESA is included in the pNext
* chain of VkPipelineRenderingCreateInfo, the depth and stencil bits will
* only be included in attachments if they are enabled.
*
* Set to MESA_VK_RP_ATTACHMENT_INFO_INVALID to indicate that attachment
* info is invalid.
@ -797,6 +803,12 @@ struct vk_render_pass_state {
/** VkCustomResolveCreateInfoEXT::customResolve */
bool custom_resolve;
/** VkRenderingAttachmentRemapInfoMESA::colorAttachmentRemap */
uint8_t color_attachment_remap[MESA_VK_MAX_COLOR_ATTACHMENTS];
/** VkRenderingAttachmentRemapInfoMESA::depthStencilAttachmentEnable */
bool depth_stencil_attachment_enable;
};
static inline bool
@ -943,7 +955,14 @@ struct vk_dynamic_graphics_state {
struct vk_color_blend_state cb;
struct {
/** MESA_VK_DYNAMIC_RP_ATTACHMENTS */
enum vk_rp_attachment_flags attachments;
/** MESA_VK_DYNAMIC_RP_REMAP */
uint8_t color_attachment_remap[MESA_VK_MAX_COLOR_ATTACHMENTS];
/** MESA_VK_DYNAMIC_RP_REMAP */
bool depth_stencil_attachment_enable;
} rp;
/** MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE */
@ -1299,6 +1318,10 @@ void
vk_cmd_set_rendering_attachment_locations(struct vk_command_buffer *cmd,
const VkRenderingAttachmentLocationInfoKHR *info);
void
vk_cmd_set_rendering_attachment_remap(struct vk_command_buffer *cmd,
const VkRenderingAttachmentRemapInfoMESA *info);
const char *
vk_dynamic_graphic_state_to_str(enum mesa_vk_dynamic_graphics_state state);

View file

@ -778,6 +778,44 @@ vk_image_layout_is_depth_only(VkImageLayout layout)
}
}
VkImageLayout
vk_image_layout_depth_only(VkImageLayout layout)
{
switch (layout) {
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
case VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL:
return VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
case VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL:
return VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL;
default:
return layout;
}
}
VkImageLayout
vk_image_layout_stencil_only(VkImageLayout layout)
{
switch (layout) {
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
case VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL:
return VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL;
case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
case VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL:
return VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL;
default:
return layout;
}
}
static VkResult
vk_image_create_get_format_list_uncompressed(struct vk_device *device,
const VkImageCreateInfo *pCreateInfo,

View file

@ -401,6 +401,8 @@ vk_image_view_subresource_range(const struct vk_image_view *view)
bool vk_image_layout_is_read_only(VkImageLayout layout,
VkImageAspectFlagBits aspect);
bool vk_image_layout_is_depth_only(VkImageLayout layout);
VkImageLayout vk_image_layout_depth_only(VkImageLayout layout);
VkImageLayout vk_image_layout_stencil_only(VkImageLayout layout);
VkImageUsageFlags vk_image_layout_to_usage_flags(VkImageLayout layout,
VkImageAspectFlagBits aspect);

File diff suppressed because it is too large Load diff

View file

@ -75,10 +75,31 @@ struct vk_subpass_attachment {
/** Resolve attachment, if any */
struct vk_subpass_attachment *resolve;
VkResolveModeFlagBits resolve_mode;
VkResolveModeFlagBits stencil_resolve_mode;
};
/***/
enum vk_subpass_merge {
/* This subpass is in the middle of a merged subpass group */
MESA_VK_SUBPASS_MERGE_MID = 0,
/* This subpass begins a merged subpass group */
MESA_VK_SUBPASS_MERGE_BEGIN = 1,
/* This subpass ends a merged subpass group */
MESA_VK_SUBPASS_MERGE_END = 2,
/** This subpass is in its own subpass group */
MESA_VK_SUBPASS_MERGE_SINGLE = MESA_VK_SUBPASS_MERGE_BEGIN |
MESA_VK_SUBPASS_MERGE_END,
};
/***/
struct vk_subpass {
enum vk_subpass_merge merge;
/** Count of all attachments referenced by this subpass */
uint32_t attachment_count;
@ -120,11 +141,10 @@ struct vk_subpass {
*/
uint32_t view_mask;
/** VkSubpassDescriptionDepthStencilResolve::depthResolveMode */
VkResolveModeFlagBits depth_resolve_mode;
VkSampleCountFlagBits mrtss_samples;
/** VkSubpassDescriptionDepthStencilResolve::stencilResolveMode */
VkResolveModeFlagBits stencil_resolve_mode;
bool has_external_src_dependency;
bool has_external_dst_dependency;
/** VkFragmentShadingRateAttachmentInfoKHR::shadingRateAttachmentTexelSize */
VkExtent2D fragment_shading_rate_attachment_texel_size;
@ -136,7 +156,16 @@ struct vk_subpass {
*
* This is in the pNext chain of pipeline_info and inheritance_info.
*/
VkAttachmentSampleCountInfoAMD sample_count_info_amd;
struct {
VkAttachmentSampleCountInfoAMD info;
VkSampleCountFlagBits samples[MESA_VK_MAX_COLOR_ATTACHMENTS];
} sample_count_amd;
/** VkRenderingAttachmentRemapInfoMESA for this subpass
*
* This is in the pNext chain of pipeline_info and inheritance_info.
*/
VkRenderingAttachmentRemapInfoMESA rar_info;
/** VkRenderingInputAttachmentIndexInfo for this subpass
*
@ -152,6 +181,8 @@ struct vk_subpass {
uint32_t stencil;
} ial;
VkFormat color_attachment_formats[MESA_VK_MAX_COLOR_ATTACHMENTS];
/** VkPipelineRenderingCreateInfo for this subpass
*
* Returned by vk_get_pipeline_rendering_create_info() if
@ -166,9 +197,6 @@ struct vk_subpass {
*/
VkCommandBufferInheritanceRenderingInfo inheritance_info;
/** VkMultisampledRenderToSingleSampledInfoEXT for this subpass */
VkMultisampledRenderToSingleSampledInfoEXT mrtss;
/** True if legacy dithering is enabled for this subpass. */
bool legacy_dithering_enabled;
};
@ -296,6 +324,19 @@ struct vk_render_pass {
VK_DEFINE_NONDISP_HANDLE_CASTS(vk_render_pass, base, VkRenderPass,
VK_OBJECT_TYPE_RENDER_PASS);
struct vk_render_pass *
vk_render_pass_create(struct vk_device *device,
const VkRenderPassCreateInfo2 *pCreateInfo,
const VkAllocationCallbacks *alloc);
/** Attempts to merge the given subpass index into the previous subpass
*
* Returns true if the merge succeeded.
*/
bool
vk_render_pass_try_merge_subpass(struct vk_render_pass *pass,
uint32_t subpass_idx);
/** Returns the VkPipelineRenderingCreateInfo for a graphics pipeline
*
* For render-pass-free drivers, this can be used in the implementation of
@ -311,6 +352,20 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(vk_render_pass, base, VkRenderPass,
const VkPipelineRenderingCreateInfo *
vk_get_pipeline_rendering_create_info(const VkGraphicsPipelineCreateInfo *info);
/** Returns the VkRenderingAttachmentRemapInfoMESA for a graphics pipeline
*
* For render-pass-free drivers, this can be used in the implementation of
* vkCreateGraphicsPipelines to get the VkRenderingAttachmentRemapInfoMESA.
* If VkGraphicsPipelineCreateInfo::renderPass is not VK_NULL_HANDLE, it will
* return the VkRenderingAttachmentRemapInfoMESA for the specified subpass.
* VkGraphicsPipelineCreateInfo::renderPass is VK_NULL_HANDLE, it will return
* NULL.
*
* :param info: |in| One of the pCreateInfos from vkCreateGraphicsPipelines
*/
const VkRenderingAttachmentRemapInfoMESA *
vk_get_pipeline_rendering_ar_info(const VkGraphicsPipelineCreateInfo *info);
/** Returns the VkRenderingInputAttachmentIndexInfo for a graphics pipeline
*
* For render-pass-free drivers, this can be used in the implementation of
@ -388,6 +443,8 @@ vk_get_rendering_attachment_flags(const VkRenderingAttachmentInfo *att);
struct vk_gcbiarr_data {
VkRenderingInfo rendering;
VkRenderingFragmentShadingRateAttachmentInfoKHR fsr_att;
VkMultisampledRenderToSingleSampledInfoEXT mrtss;
VkRenderingAttachmentRemapInfoMESA rar;
VkRenderingAttachmentInfo attachments[];
};

View file

@ -15,6 +15,8 @@
#ifndef VK_INTERNAL_EXTS_H
#define VK_INTERNAL_EXTS_H
#include "vulkan/runtime/vk_limits.h"
#include <vulkan/vulkan_core.h>
#include <stdbool.h>
@ -123,6 +125,43 @@ typedef struct VkRenderingAttachmentInitialLayoutInfoMESA {
#define VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA_cast \
VkRenderingAttachmentInitialLayoutInfoMESA
/* Can extend any of the following:
*
* - VkPipelineCreateInfo
* - VkRenderingInfo
* - VkCommandBufferInheritanceRenderingInfo
*
* When chained into VkRenderingInfo, the driver must first begin the render,
* including any attachment loads, and then set the remap. The remap does not
* apply to the VkRenderingInfo itself.
*/
typedef struct VkRenderingAttachmentRemapInfoMESA {
VkStructureType sType;
const void* pNext;
/** A mapping from attachments (as per the vkBeginRendering() numbering)
* to logical attachments used by other Vulkan commands such
* CmdClearAttachments() or CmdSetColorBlendEquationEXT().
*
* Unlike VkRenderingAttachmentLocationInfo, this applies to all Vulkan
* commands and structs other than CmdBeginRendering() and
* VkCommandBufferInheritanceRenderingInfo, into which it can be chained.
*/
uint32_t colorAttachmentRemap[MESA_VK_MAX_COLOR_ATTACHMENTS];
/** True if the depth/stencil attachment should be enabled.
*
* If false, the driver will behave as if the depth attachment is not
* present, even though it may still be bound. This implies disabling the
* depth and stencil tests as well as depth writes.
*/
VkBool32 depthStencilAttachmentEnable;
} VkRenderingAttachmentRemapInfoMESA;
#define VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_REMAP_INFO_MESA \
(VkStructureType)1000044902
#define VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_REMAP_INFO_MESA_cast \
VkRenderingAttachmentRemapInfoMESA
struct nir_shader;