nvk: Emit SET_ANTI_ALIAS at draw time when no render targets are bound

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/27025>
This commit is contained in:
Faith Ekstrand 2024-01-11 18:08:56 -06:00 committed by Marge Bot
parent 48d510ac57
commit 148ea7792f
2 changed files with 55 additions and 4 deletions

View file

@ -91,6 +91,7 @@ struct nvk_rendering_state {
VkRect2D area;
uint32_t layer_count;
uint32_t view_mask;
uint32_t samples;
uint32_t color_att_count;
struct nvk_attachment color_att[NVK_MAX_RTS];

View file

@ -455,6 +455,9 @@ nvk_cmd_buffer_dirty_render_pass(struct nvk_cmd_buffer *cmd)
BITSET_SET(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_WRITE_ENABLE);
BITSET_SET(dyn->dirty, MESA_VK_DYNAMIC_DS_DEPTH_BOUNDS_TEST_ENABLE);
BITSET_SET(dyn->dirty, MESA_VK_DYNAMIC_DS_STENCIL_TEST_ENABLE);
/* This may depend on render targets for ESO */
BITSET_SET(dyn->dirty, MESA_VK_DYNAMIC_MS_RASTERIZATION_SAMPLES);
}
void
@ -496,6 +499,7 @@ nvk_cmd_buffer_begin_graphics(struct nvk_cmd_buffer *cmd,
render->area = (VkRect2D) { };
render->layer_count = 0;
render->view_mask = inheritance_info->viewMask;
render->samples = inheritance_info->rasterizationSamples;
render->color_att_count = inheritance_info->colorAttachmentCount;
for (uint32_t i = 0; i < render->color_att_count; i++) {
@ -592,6 +596,7 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer,
render->area = pRenderingInfo->renderArea;
render->view_mask = pRenderingInfo->viewMask;
render->layer_count = pRenderingInfo->layerCount;
render->samples = 0;
const uint32_t layer_count =
render->view_mask ? util_last_bit(render->view_mask) :
@ -647,6 +652,7 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer,
assert(sample_layout == NIL_SAMPLE_LAYOUT_INVALID ||
sample_layout == image->planes[ip].nil.sample_layout);
sample_layout = image->planes[ip].nil.sample_layout;
render->samples = image->vk.samples;
uint64_t addr = nvk_image_base_address(image, ip) + level->offset_B;
@ -767,6 +773,7 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer,
assert(sample_layout == NIL_SAMPLE_LAYOUT_INVALID ||
sample_layout == nil_image.sample_layout);
sample_layout = nil_image.sample_layout;
render->samples = image->vk.samples;
P_MTHD(p, NV9097, SET_ZT_A);
P_NV9097_SET_ZT_A(p, addr >> 32);
@ -807,10 +814,28 @@ nvk_CmdBeginRendering(VkCommandBuffer commandBuffer,
P_IMMD(p, NV9097, SET_ZT_SELECT, 0 /* target_count */);
}
if (sample_layout == NIL_SAMPLE_LAYOUT_INVALID)
sample_layout = NIL_SAMPLE_LAYOUT_1X1;
P_IMMD(p, NV9097, SET_ANTI_ALIAS, nil_to_nv9097_samples_mode(sample_layout));
/* From the Vulkan 1.3.275 spec:
*
* "It is legal for a subpass to use no color or depth/stencil
* attachments, either because it has no attachment references or
* because all of them are VK_ATTACHMENT_UNUSED. This kind of subpass
* can use shader side effects such as image stores and atomics to
* produce an output. In this case, the subpass continues to use the
* width, height, and layers of the framebuffer to define the dimensions
* of the rendering area, and the rasterizationSamples from each
* pipelines VkPipelineMultisampleStateCreateInfo to define the number
* of samples used in rasterization;"
*
* In the case where we have attachments, we emit SET_ANTI_ALIAS here
* because SET_COLOR_TARGET_* and SET_ZT_* don't have any other way of
* specifying the sample layout and we want to ensure it matches. When
* we don't have any attachments, we defer SET_ANTI_ALIAS to draw time
* where we base it on dynamic rasterizationSamples.
*/
if (sample_layout != NIL_SAMPLE_LAYOUT_INVALID) {
P_IMMD(p, NV9097, SET_ANTI_ALIAS,
nil_to_nv9097_samples_mode(sample_layout));
}
if (render->flags & VK_RENDERING_RESUMING_BIT)
return;
@ -1398,9 +1423,34 @@ static void
nvk_flush_ms_state(struct nvk_cmd_buffer *cmd)
{
struct nvk_descriptor_state *desc = &cmd->state.gfx.descriptors;
const struct nvk_rendering_state *render = &cmd->state.gfx.render;
const struct vk_dynamic_graphics_state *dyn =
&cmd->vk.dynamic_graphics_state;
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_MS_RASTERIZATION_SAMPLES)) {
/* When we don't have any attachments, we can't know the sample count
* from the render pass so we need to emit SET_ANTI_ALIAS here. See the
* comment in nvk_BeginRendering() for more details.
*/
if (render->samples == 0) {
struct nv_push *p = nvk_cmd_buffer_push(cmd, 2);
/* Multisample information MAY be missing (rasterizationSamples == 0)
* if rasterizer discard is enabled. However, this isn't valid in
* the hardware so always use at least one sample.
*/
const uint32_t samples = MAX2(1, dyn->ms.rasterization_samples);
enum nil_sample_layout layout = nil_choose_sample_layout(samples);
P_IMMD(p, NV9097, SET_ANTI_ALIAS, nil_to_nv9097_samples_mode(layout));
} else {
/* Multisample information MAY be missing (rasterizationSamples == 0)
* if rasterizer discard is enabled.
*/
assert(dyn->ms.rasterization_samples == 0 ||
dyn->ms.rasterization_samples == render->samples);
}
}
if (BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_MS_ALPHA_TO_COVERAGE_ENABLE) ||
BITSET_TEST(dyn->dirty, MESA_VK_DYNAMIC_MS_ALPHA_TO_ONE_ENABLE)) {
struct nv_push *p = nvk_cmd_buffer_push(cmd, 2);