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 VKAPI_ATTR void VKAPI_CALL
nvk_CmdClearAttachments(VkCommandBuffer commandBuffer, nvk_CmdClearAttachments(VkCommandBuffer commandBuffer,
uint32_t attachmentCount, uint32_t attachmentCount,
@ -189,7 +204,9 @@ nvk_CmdClearAttachments(VkCommandBuffer commandBuffer,
if (pAttachments[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT) if (pAttachments[i].aspectMask != VK_IMAGE_ASPECT_COLOR_BIT)
continue; 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; continue;
VkClearColorValue color = pAttachments[i].clearValue.color; 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, 2, color.uint32[2]);
P_NV9097_SET_COLOR_CLEAR_VALUE(p, 3, color.uint32[3]); P_NV9097_SET_COLOR_CLEAR_VALUE(p, 3, color.uint32[3]);
emit_clear_rects(cmd, pAttachments[i].colorAttachment, emit_clear_rects(cmd, ct, clear_depth, clear_stencil, rectCount, pRects);
clear_depth, clear_stencil, rectCount, pRects);
/* We only need to clear depth/stencil once */ /* We only need to clear depth/stencil once */
clear_depth = clear_stencil = false; 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 = render->stencil_att.vk_format =
inheritance_info->stencilAttachmentFormat; 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 = { const VkRenderingAttachmentLocationInfoKHR att_loc_info_default = {
.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_LOCATION_INFO_KHR, .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_LOCATION_INFO_KHR,
.colorAttachmentCount = inheritance_info->colorAttachmentCount, .colorAttachmentCount = inheritance_info->colorAttachmentCount,
@ -1404,8 +1409,17 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer,
if (sample_layout != NIL_SAMPLE_LAYOUT_INVALID) if (sample_layout != NIL_SAMPLE_LAYOUT_INVALID)
nvk_cmd_set_sample_layout(cmd, sample_layout); 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; 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++) { for (uint32_t i = 0; i < pRenderingInfo->colorAttachmentCount; i++) {
const struct nvk_image_view *iview = render->color_att[i].iview; 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); 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 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 = const struct vk_dynamic_graphics_state *dyn =
&cmd->vk.dynamic_graphics_state; &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 && bool enable = dyn->ds.depth.test_enable &&
dyn->rp.depth_stencil_attachment_enable &&
render->depth_att.vk_format != VK_FORMAT_UNDEFINED; render->depth_att.vk_format != VK_FORMAT_UNDEFINED;
P_IMMD(p, NV9097, SET_DEPTH_TEST, enable); 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 && bool enable = dyn->ds.depth.write_enable &&
dyn->rp.depth_stencil_attachment_enable &&
render->depth_att.vk_format != VK_FORMAT_UNDEFINED; render->depth_att.vk_format != VK_FORMAT_UNDEFINED;
P_IMMD(p, NV9097, SET_DEPTH_WRITE, enable); 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)); 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 && bool enable = dyn->ds.stencil.test_enable &&
dyn->rp.depth_stencil_attachment_enable &&
render->stencil_att.vk_format != VK_FORMAT_UNDEFINED; render->stencil_att.vk_format != VK_FORMAT_UNDEFINED;
P_IMMD(p, NV9097, SET_STENCIL_TEST, enable); 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); 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 static void
nvk_flush_cb_state(struct nvk_cmd_buffer *cmd) 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); 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++) { 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++) { for (uint8_t a = 0; a < render->color_att_count; a++) {
const struct vk_color_blend_attachment_state *att = 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_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_SEPARATE_FOR_ALPHA(p, a, ENABLE_TRUE);
P_NV9097_SET_BLEND_PER_TARGET_COLOR_OP(p, a, 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) || 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_CB_COLOR_WRITE_ENABLES) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_RP_ATTACHMENTS) || 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)) { BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP)) {
uint32_t color_write_enables = 0x0; uint32_t color_write_enables = 0x0;
for (uint8_t a = 0; a < render->color_att_count; a++) { 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); color_write_enables |= 0xf << (4 * a);
} }
uint32_t cb_att_write_mask = 0x0; uint32_t cb_att_write_mask = 0x0;
for (uint8_t a = 0; a < render->color_att_count; a++) for (uint8_t a = 0; a < render->color_att_count; a++) {
cb_att_write_mask |= dyn->cb.attachments[a].write_mask << (a * 4); 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; uint32_t rp_att_write_mask = 0x0;
for (uint8_t a = 0; a < MESA_VK_MAX_COLOR_ATTACHMENTS; a++) { 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); rp_att_write_mask |= 0xf << (4 * a);
} }
uint32_t att_has_loc_mask = 0x0; uint32_t att_has_loc_mask = 0x0;
for (uint8_t a = 0; a < MESA_VK_MAX_COLOR_ATTACHMENTS; a++) { 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); att_has_loc_mask |= 0xf << (4 * a);
} }
@ -3455,19 +3518,22 @@ nvk_flush_cb_state(struct nvk_cmd_buffer *cmd)
att_has_loc_mask); 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}; int8_t loc_att[NVK_MAX_RTS] = { -1, -1, -1, -1, -1, -1, -1, -1};
uint8_t max_loc = 0; uint8_t max_loc = 0;
uint32_t att_used = 0; uint32_t att_used = 0;
for (uint8_t a = 0; a < render->color_att_count; a++) { 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; continue;
att_used |= BITFIELD_BIT(a); att_used |= BITFIELD_BIT(a);
assert(dyn->cal.color_map[a] < NVK_MAX_RTS); assert(loc < NVK_MAX_RTS);
loc_att[dyn->cal.color_map[a]] = a; loc_att[loc] = a;
max_loc = MAX2(max_loc, dyn->cal.color_map[a]); max_loc = MAX2(max_loc, loc);
} }
for (uint8_t l = 0; l < NVK_MAX_RTS; l++) { 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.internal_buffer_offset = cbuf_offset;
cfg.clear = rt_clear(&fb->rts[idx]); cfg.clear = rt_clear(&fb->rts[idx]);
cfg.dithering_enable = true; 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 #if PAN_ARCH >= 7
cfg.writeback_block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED; cfg.writeback_block_format = MALI_BLOCK_FORMAT_TILED_U_INTERLEAVED;
#endif #endif

View file

@ -455,6 +455,8 @@ prepare_fs_driver_set(struct panvk_cmd_buffer *cmdbuf)
static bool static bool
has_depth_att(struct panvk_cmd_buffer *cmdbuf) 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 & return (cmdbuf->state.gfx.render.bound_attachments &
MESA_VK_RP_ATTACHMENT_DEPTH_BIT) != 0; MESA_VK_RP_ATTACHMENT_DEPTH_BIT) != 0;
} }
@ -462,6 +464,8 @@ has_depth_att(struct panvk_cmd_buffer *cmdbuf)
static bool static bool
has_stencil_att(struct panvk_cmd_buffer *cmdbuf) 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 & return (cmdbuf->state.gfx.render.bound_attachments &
MESA_VK_RP_ATTACHMENT_STENCIL_BIT) != 0; 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_BLEND_EQUATIONS) ||
dyn_gfx_state_dirty(cmdbuf, CB_WRITE_MASKS) || dyn_gfx_state_dirty(cmdbuf, CB_WRITE_MASKS) ||
dyn_gfx_state_dirty(cmdbuf, CB_BLEND_CONSTANTS) || dyn_gfx_state_dirty(cmdbuf, CB_BLEND_CONSTANTS) ||
dyn_gfx_state_dirty(cmdbuf, RP_REMAP) ||
dyn_gfx_state_dirty(cmdbuf, COLOR_ATTACHMENT_MAP) || dyn_gfx_state_dirty(cmdbuf, COLOR_ATTACHMENT_MAP) ||
fs_user_dirty(cmdbuf) || gfx_state_dirty(cmdbuf, RENDER_STATE); 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_ENABLE) ||
dyn_gfx_state_dirty(cmdbuf, RS_DEPTH_BIAS_FACTORS) || dyn_gfx_state_dirty(cmdbuf, RS_DEPTH_BIAS_FACTORS) ||
dyn_gfx_state_dirty(cmdbuf, MS_ALPHA_TO_COVERAGE_ENABLE) || 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) || dyn_gfx_state_dirty(cmdbuf, INPUT_ATTACHMENT_MAP) ||
fs_user_dirty(cmdbuf) || gfx_state_dirty(cmdbuf, OQ); 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_SAMPLE_MASK) ||
dyn_gfx_state_dirty(cmdbuf, MS_ALPHA_TO_COVERAGE_ENABLE) || 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, MS_ALPHA_TO_ONE_ENABLE) ||
dyn_gfx_state_dirty(cmdbuf, RP_REMAP) ||
/* writes_depth() uses vk_depth_stencil_state */ /* writes_depth() uses vk_depth_stencil_state */
dyn_gfx_state_dirty(cmdbuf, DS_DEPTH_TEST_ENABLE) || dyn_gfx_state_dirty(cmdbuf, DS_DEPTH_TEST_ENABLE) ||
dyn_gfx_state_dirty(cmdbuf, DS_DEPTH_WRITE_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; att_loc_info = &att_loc_info_default;
vk_cmd_set_rendering_attachment_locations(&cmdbuf->vk, att_loc_info); 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 VKAPI_ATTR void VKAPI_CALL

View file

@ -92,6 +92,8 @@ is_indirect_draw(const struct panvk_draw_data *draw)
static bool static bool
has_depth_att(struct panvk_cmd_buffer *cmdbuf) 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 & return (cmdbuf->state.gfx.render.bound_attachments &
MESA_VK_RP_ATTACHMENT_DEPTH_BIT) != 0; MESA_VK_RP_ATTACHMENT_DEPTH_BIT) != 0;
} }
@ -99,6 +101,8 @@ has_depth_att(struct panvk_cmd_buffer *cmdbuf)
static bool static bool
has_stencil_att(struct panvk_cmd_buffer *cmdbuf) 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 & return (cmdbuf->state.gfx.render.bound_attachments &
MESA_VK_RP_ATTACHMENT_STENCIL_BIT) != 0; 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_SAMPLE_MASK) ||
dyn_gfx_state_dirty(cmdbuf, MS_ALPHA_TO_COVERAGE_ENABLE) || 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, 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, FS) || gfx_state_dirty(cmdbuf, OQ) ||
gfx_state_dirty(cmdbuf, RENDER_STATE); 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] = {}; uint64_t blend_shaders[8] = {};
/* All bits set to one encodes unused fixed-function blend constant. */ /* All bits set to one encodes unused fixed-function blend constant. */
unsigned ff_blend_constant = ~0; 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, 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); 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)); 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; rt->equation.color_mask = 0;
continue; continue;
} }
if (!(cb->color_write_enables & BITFIELD_BIT(i))) { if (color_attachment_formats[rt_idx] == VK_FORMAT_UNDEFINED) {
rt->equation.color_mask = 0; rt->equation.color_mask = 0;
continue; continue;
} }
if (color_attachment_formats[i] == VK_FORMAT_UNDEFINED) { if (!cb->attachments[att].write_mask) {
rt->equation.color_mask = 0; rt->equation.color_mask = 0;
continue; continue;
} }
if (!cb->attachments[i].write_mask) { rt->format = vk_format_to_pipe_format(color_attachment_formats[rt_idx]);
rt->equation.color_mask = 0; rt->nr_samples = color_attachment_samples[rt_idx];
continue;
}
rt->format = vk_format_to_pipe_format(color_attachment_formats[i]);
/* Disable blending for LOGICOP_NOOP unless the format is float/srgb */ /* Disable blending for LOGICOP_NOOP unless the format is float/srgb */
if (bs.logicop_enable && bs.logicop_func == PIPE_LOGICOP_NOOP && 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; continue;
} }
rt->nr_samples = color_attachment_samples[i]; rt->equation.blend_enable = cb->attachments[att].blend_enable;
rt->equation.blend_enable = cb->attachments[i].blend_enable; rt->equation.color_mask = cb->attachments[att].write_mask;
rt->equation.color_mask = cb->attachments[i].write_mask;
rt->equation.rgb_func = 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 = 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 = 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 = 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 = 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 = 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); bool dest_has_alpha = util_format_has_alpha(rt->format);
if (!dest_has_alpha) { 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); blend_info->any_dest_read |= pan_blend_reads_dest(rt->equation);
if (blend_needs_shader(&bs, i, &ff_blend_constant)) { if (blend_needs_shader(&bs, rt_idx, &ff_blend_constant)) {
nir_alu_type src0_type = fs_info->bifrost.blend[i].type; nir_alu_type src0_type = fs_info->bifrost.blend[loc].type;
nir_alu_type src1_type = fs_info->bifrost.blend_src1_type; nir_alu_type src1_type = fs_info->bifrost.blend_src1_type;
VkResult result = get_blend_shader(dev, &bs, src0_type, 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) if (result != VK_SUCCESS)
return result; return result;
@ -429,13 +437,13 @@ panvk_per_arch(blend_emit_descs)(struct panvk_cmd_buffer *cmdbuf,
ff_blend_constant = 0; ff_blend_constant = 0;
/* Now that we've collected all the information, we can emit. */ /* Now that we've collected all the information, we can emit. */
for (uint8_t i = 0; i < blend_count; i++) { for (uint8_t loc = 0; loc < blend_count; loc++) {
uint32_t catt_idx = remap_catts[i]; uint32_t rt_idx = loc_rt[loc];
uint64_t blend_shader = 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, emit_blend_desc(fs_info, fs_code, &bs, loc, rt_idx,
blend_shader, ff_blend_constant, &bds[i]); blend_shader, ff_blend_constant, &bds[loc]);
} }
if (blend_info->shader_loads_blend_const) 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); 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 void

View file

@ -235,6 +235,8 @@ panvk_per_arch(CmdClearAttachments)(VkCommandBuffer commandBuffer,
const VkClearRect *pRects) const VkClearRect *pRects)
{ {
VK_FROM_HANDLE(panvk_cmd_buffer, cmdbuf, commandBuffer); 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_device *dev = to_panvk_device(cmdbuf->vk.base.device);
struct panvk_cmd_meta_graphics_save_ctx save = {0}; struct panvk_cmd_meta_graphics_save_ctx save = {0};
struct vk_meta_rendering_info render = { 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; 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); panvk_per_arch(cmd_meta_gfx_start)(cmdbuf, &save);
vk_meta_clear_attachments(&cmdbuf->vk, &dev->meta, &render, attachmentCount, vk_meta_clear_attachments(&cmdbuf->vk, &dev->meta, &render,
pAttachments, rectCount, pRects); attachment_count, attachments,
rectCount, pRects);
panvk_per_arch(cmd_meta_gfx_end)(cmdbuf, &save); 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, _mesa_blake3_update(&blake3_ctx, &state->rp->view_mask,
sizeof(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) if (state->ial)
_mesa_blake3_update(&blake3_ctx, state->ial, sizeof(*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) if (state && state->ms && state->ms->sample_shading_enable)
nir->info.fs.uses_sample_shading = true; 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 */ /* We need to lower input attachments before we lower descriptors */
NIR_PASS(_, nir, panvk_per_arch(nir_lower_input_attachment_loads), NIR_PASS(_, nir, panvk_per_arch(nir_lower_input_attachment_loads),
state, &variant->fs.input_attachment_read); 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; 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++) { for (uint32_t i = 0; i < r_info->colorAttachmentCount; i++) {
if (rp->color_attachment_formats[i] != VK_FORMAT_UNDEFINED) if (rp->color_attachment_formats[i] != VK_FORMAT_UNDEFINED)
rp->attachments |= MESA_VK_RP_ATTACHMENT_COLOR_BIT(i); 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) const struct vk_render_pass_state *rp)
{ {
dst->rp.attachments = rp->attachments; 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) \ #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_ARRAY(CB_BLEND_CONSTANTS, cb.blend_constants, 4);
COPY_IF_SET(RP_ATTACHMENTS, rp.attachments); 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)) { if (IS_SET_IN_SRC(INPUT_ATTACHMENT_MAP)) {
COPY_MEMBER(INPUT_ATTACHMENT_MAP, ial.color_attachment_count); COPY_MEMBER(INPUT_ATTACHMENT_MAP, ial.color_attachment_count);
@ -3191,6 +3215,23 @@ vk_common_CmdSetRenderingAttachmentLocationsKHR(
vk_cmd_set_rendering_attachment_locations(cmd, pLocationInfo); 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 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdSetRenderingInputAttachmentIndicesKHR( vk_common_CmdSetRenderingInputAttachmentIndicesKHR(
VkCommandBuffer commandBuffer, VkCommandBuffer commandBuffer,

View file

@ -27,6 +27,7 @@
#include "vulkan/vulkan_core.h" #include "vulkan/vulkan_core.h"
#include "vk_limits.h" #include "vk_limits.h"
#include "vk_internal_exts.h"
#include "util/bitset.h" #include "util/bitset.h"
#include "util/enum_operators.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_WRITE_MASKS,
MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS, MESA_VK_DYNAMIC_CB_BLEND_CONSTANTS,
MESA_VK_DYNAMIC_RP_ATTACHMENTS, MESA_VK_DYNAMIC_RP_ATTACHMENTS,
MESA_VK_DYNAMIC_RP_REMAP,
MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE, MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE,
MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP, MESA_VK_DYNAMIC_COLOR_ATTACHMENT_MAP,
MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP, MESA_VK_DYNAMIC_INPUT_ATTACHMENT_MAP,
@ -768,6 +770,10 @@ struct vk_color_attachment_location_state {
/***/ /***/
struct vk_render_pass_state { struct vk_render_pass_state {
/** Set of image aspects bound as color/depth/stencil attachments /** 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 * Set to MESA_VK_RP_ATTACHMENT_INFO_INVALID to indicate that attachment
* info is invalid. * info is invalid.
@ -797,6 +803,12 @@ struct vk_render_pass_state {
/** VkCustomResolveCreateInfoEXT::customResolve */ /** VkCustomResolveCreateInfoEXT::customResolve */
bool custom_resolve; 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 static inline bool
@ -943,7 +955,14 @@ struct vk_dynamic_graphics_state {
struct vk_color_blend_state cb; struct vk_color_blend_state cb;
struct { struct {
/** MESA_VK_DYNAMIC_RP_ATTACHMENTS */
enum vk_rp_attachment_flags 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; } rp;
/** MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE */ /** MESA_VK_DYNAMIC_ATTACHMENT_FEEDBACK_LOOP_ENABLE */
@ -1299,6 +1318,10 @@ void
vk_cmd_set_rendering_attachment_locations(struct vk_command_buffer *cmd, vk_cmd_set_rendering_attachment_locations(struct vk_command_buffer *cmd,
const VkRenderingAttachmentLocationInfoKHR *info); const VkRenderingAttachmentLocationInfoKHR *info);
void
vk_cmd_set_rendering_attachment_remap(struct vk_command_buffer *cmd,
const VkRenderingAttachmentRemapInfoMESA *info);
const char * const char *
vk_dynamic_graphic_state_to_str(enum mesa_vk_dynamic_graphics_state state); 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 static VkResult
vk_image_create_get_format_list_uncompressed(struct vk_device *device, vk_image_create_get_format_list_uncompressed(struct vk_device *device,
const VkImageCreateInfo *pCreateInfo, 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, bool vk_image_layout_is_read_only(VkImageLayout layout,
VkImageAspectFlagBits aspect); VkImageAspectFlagBits aspect);
bool vk_image_layout_is_depth_only(VkImageLayout layout); 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, VkImageUsageFlags vk_image_layout_to_usage_flags(VkImageLayout layout,
VkImageAspectFlagBits aspect); 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 */ /** Resolve attachment, if any */
struct vk_subpass_attachment *resolve; 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 { struct vk_subpass {
enum vk_subpass_merge merge;
/** Count of all attachments referenced by this subpass */ /** Count of all attachments referenced by this subpass */
uint32_t attachment_count; uint32_t attachment_count;
@ -120,11 +141,10 @@ struct vk_subpass {
*/ */
uint32_t view_mask; uint32_t view_mask;
/** VkSubpassDescriptionDepthStencilResolve::depthResolveMode */ VkSampleCountFlagBits mrtss_samples;
VkResolveModeFlagBits depth_resolve_mode;
/** VkSubpassDescriptionDepthStencilResolve::stencilResolveMode */ bool has_external_src_dependency;
VkResolveModeFlagBits stencil_resolve_mode; bool has_external_dst_dependency;
/** VkFragmentShadingRateAttachmentInfoKHR::shadingRateAttachmentTexelSize */ /** VkFragmentShadingRateAttachmentInfoKHR::shadingRateAttachmentTexelSize */
VkExtent2D fragment_shading_rate_attachment_texel_size; 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. * 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 /** VkRenderingInputAttachmentIndexInfo for this subpass
* *
@ -152,6 +181,8 @@ struct vk_subpass {
uint32_t stencil; uint32_t stencil;
} ial; } ial;
VkFormat color_attachment_formats[MESA_VK_MAX_COLOR_ATTACHMENTS];
/** VkPipelineRenderingCreateInfo for this subpass /** VkPipelineRenderingCreateInfo for this subpass
* *
* Returned by vk_get_pipeline_rendering_create_info() if * Returned by vk_get_pipeline_rendering_create_info() if
@ -166,9 +197,6 @@ struct vk_subpass {
*/ */
VkCommandBufferInheritanceRenderingInfo inheritance_info; VkCommandBufferInheritanceRenderingInfo inheritance_info;
/** VkMultisampledRenderToSingleSampledInfoEXT for this subpass */
VkMultisampledRenderToSingleSampledInfoEXT mrtss;
/** True if legacy dithering is enabled for this subpass. */ /** True if legacy dithering is enabled for this subpass. */
bool legacy_dithering_enabled; bool legacy_dithering_enabled;
}; };
@ -296,6 +324,19 @@ struct vk_render_pass {
VK_DEFINE_NONDISP_HANDLE_CASTS(vk_render_pass, base, VkRenderPass, VK_DEFINE_NONDISP_HANDLE_CASTS(vk_render_pass, base, VkRenderPass,
VK_OBJECT_TYPE_RENDER_PASS); 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 /** Returns the VkPipelineRenderingCreateInfo for a graphics pipeline
* *
* For render-pass-free drivers, this can be used in the implementation of * 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 * const VkPipelineRenderingCreateInfo *
vk_get_pipeline_rendering_create_info(const VkGraphicsPipelineCreateInfo *info); 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 /** Returns the VkRenderingInputAttachmentIndexInfo for a graphics pipeline
* *
* For render-pass-free drivers, this can be used in the implementation of * 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 { struct vk_gcbiarr_data {
VkRenderingInfo rendering; VkRenderingInfo rendering;
VkRenderingFragmentShadingRateAttachmentInfoKHR fsr_att; VkRenderingFragmentShadingRateAttachmentInfoKHR fsr_att;
VkMultisampledRenderToSingleSampledInfoEXT mrtss;
VkRenderingAttachmentRemapInfoMESA rar;
VkRenderingAttachmentInfo attachments[]; VkRenderingAttachmentInfo attachments[];
}; };

View file

@ -15,6 +15,8 @@
#ifndef VK_INTERNAL_EXTS_H #ifndef VK_INTERNAL_EXTS_H
#define VK_INTERNAL_EXTS_H #define VK_INTERNAL_EXTS_H
#include "vulkan/runtime/vk_limits.h"
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
#include <stdbool.h> #include <stdbool.h>
@ -123,6 +125,43 @@ typedef struct VkRenderingAttachmentInitialLayoutInfoMESA {
#define VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA_cast \ #define VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA_cast \
VkRenderingAttachmentInitialLayoutInfoMESA 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; struct nir_shader;