vkd3d: Do not create pipeline variants for NULL RTVs.

Signed-off-by: Philip Rebohle <philip.rebohle@tu-dortmund.de>
This commit is contained in:
Philip Rebohle 2022-03-22 00:37:55 +01:00 committed by Hans-Kristian Arntzen
parent 63530501a5
commit 34f5fc6a31
3 changed files with 21 additions and 49 deletions

View File

@ -4377,7 +4377,6 @@ static void d3d12_command_list_reset_api_state(struct d3d12_command_list *list,
list->fb_width = 0;
list->fb_height = 0;
list->fb_layer_count = 0;
list->rtv_nonnull_mask = 0;
list->xfb_enabled = false;
@ -4531,25 +4530,22 @@ static bool d3d12_command_list_update_rendering_info(struct d3d12_command_list *
{
struct vkd3d_rendering_info *rendering_info = &list->rendering_info;
struct d3d12_graphics_pipeline_state *graphics;
uint32_t rtv_mask;
unsigned int i;
if (rendering_info->state_flags & VKD3D_RENDERING_CURRENT)
return true;
graphics = &list->state->graphics;
rtv_mask = graphics->rtv_active_mask & list->rtv_nonnull_mask;
rendering_info->rtv_mask = rtv_mask;
rendering_info->rtv_mask = graphics->rtv_active_mask;
rendering_info->info.colorAttachmentCount = vkd3d_get_color_attachment_count(graphics->rtv_active_mask);
rendering_info->rtv_mask = rtv_mask;
/* The pipeline has fallback PSO in case we're attempting to render to unbound RTV. */
for (i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
{
VkRenderingAttachmentInfoKHR *attachment = &rendering_info->rtv[i];
if (rtv_mask & (1u << i))
if ((graphics->rtv_active_mask & (1u << i)) && list->rtvs[i].view)
{
attachment->imageView = list->rtvs[i].view->vk_image_view;
attachment->imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
@ -4697,11 +4693,11 @@ static bool d3d12_command_list_update_graphics_pipeline(struct d3d12_command_lis
}
/* Try to grab the pipeline we compiled ahead of time. If we cannot do so, fall back. */
if (!(vk_pipeline = d3d12_pipeline_state_get_pipeline(list->state, &list->dynamic_state,
list->rtv_nonnull_mask, list->dsv.format, &new_active_flags)))
if (!(vk_pipeline = d3d12_pipeline_state_get_pipeline(list->state,
&list->dynamic_state, list->dsv.format, &new_active_flags)))
{
if (!(vk_pipeline = d3d12_pipeline_state_get_or_create_pipeline(list->state, &list->dynamic_state,
list->rtv_nonnull_mask, list->dsv.format, &new_active_flags)))
if (!(vk_pipeline = d3d12_pipeline_state_get_or_create_pipeline(list->state,
&list->dynamic_state, list->dsv.format, &new_active_flags)))
return false;
}
@ -4718,7 +4714,7 @@ static bool d3d12_command_list_update_graphics_pipeline(struct d3d12_command_lis
}
/* If we need to bind or unbind certain render targets or if the DSV layout changed, interrupt rendering */
if (((list->state->graphics.rtv_active_mask & list->rtv_nonnull_mask) != list->rendering_info.rtv_mask) ||
if ((list->state->graphics.rtv_active_mask != list->rendering_info.rtv_mask) ||
(dsv_layout != list->rendering_info.dsv.imageLayout))
{
d3d12_command_list_invalidate_rendering_info(list);
@ -7989,7 +7985,6 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(d3d12_comman
const struct d3d12_graphics_pipeline_state *graphics;
VkFormat prev_dsv_format, next_dsv_format;
const struct d3d12_rtv_desc *rtv_desc;
uint32_t prev_rtv_non_null_mask;
unsigned int i;
TRACE("iface %p, render_target_descriptor_count %u, render_target_descriptors %p, "
@ -8020,9 +8015,6 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(d3d12_comman
list->dsv_layout = VK_IMAGE_LAYOUT_UNDEFINED;
list->dsv_plane_optimal_mask = 0;
prev_rtv_non_null_mask = list->rtv_nonnull_mask;
list->rtv_nonnull_mask = 0;
for (i = 0; i < render_target_descriptor_count; ++i)
{
if (single_descriptor_handle)
@ -8044,7 +8036,6 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(d3d12_comman
d3d12_command_list_track_resource_usage(list, rtv_desc->resource, true);
list->rtvs[i] = *rtv_desc;
list->rtv_nonnull_mask |= 1u << i;
list->fb_width = min(list->fb_width, rtv_desc->width);
list->fb_height = min(list->fb_height, rtv_desc->height);
list->fb_layer_count = min(list->fb_layer_count, rtv_desc->layer_count);
@ -8072,11 +8063,12 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(d3d12_comman
if (d3d12_pipeline_state_is_graphics(list->state))
{
graphics = &list->state->graphics;
if ((prev_dsv_format != next_dsv_format && d3d12_graphics_pipeline_state_is_depth_stencil_sensitive(graphics)) ||
((prev_rtv_non_null_mask ^ list->rtv_nonnull_mask) & graphics->rtv_active_mask))
if (prev_dsv_format != next_dsv_format && d3d12_graphics_pipeline_state_is_depth_stencil_sensitive(graphics))
{
/* If we change the NULL-ness of any attachments, we are at risk of having to use fallback pipelines.
* Invalidate the pipeline since we'll have to refresh the VkRenderPass and VkPipeline. */
/* If we change the NULL-ness of the depth-stencil attachment, we are
* at risk of having to use fallback pipelines. Invalidate the pipeline
* since we'll have to refresh the VkRenderingInfo and VkPipeline. */
d3d12_command_list_invalidate_current_pipeline(list, false);
}
}

View File

@ -3873,7 +3873,6 @@ VkPipeline d3d12_pipeline_state_create_pipeline_variant(struct d3d12_pipeline_st
VkGraphicsPipelineCreateInfo pipeline_desc;
VkPipelineViewportStateCreateInfo vp_desc;
VkPipelineCreationFeedbackEXT feedback;
uint32_t rtv_active_mask;
VkPipeline vk_pipeline;
unsigned int i;
VkResult vr;
@ -3941,10 +3940,9 @@ VkPipeline d3d12_pipeline_state_create_pipeline_variant(struct d3d12_pipeline_st
rendering_info.depthAttachmentFormat = dsv_format ? dsv_format->vk_format : VK_FORMAT_UNDEFINED;
rendering_info.stencilAttachmentFormat = dsv_format ? dsv_format->vk_format : VK_FORMAT_UNDEFINED;
rtv_active_mask = key ? key->rtv_active_mask : graphics->rtv_active_mask;
for (i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; i++)
{
if (rtv_active_mask & (1u << i))
if (graphics->rtv_active_mask & (1u << i))
rtv_formats[i] = graphics->rtv_formats[i];
else
rtv_formats[i] = VK_FORMAT_UNDEFINED;
@ -3991,12 +3989,6 @@ VkPipeline d3d12_pipeline_state_create_pipeline_variant(struct d3d12_pipeline_st
pipeline_desc.pDepthStencilState = &fallback_ds_desc;
}
if (graphics->rtv_active_mask != rtv_active_mask)
{
TRACE("Compiling %p with fallback RTV write mask (PSO = 0x%x, RT = 0x%x).\n", state,
state->graphics.rtv_active_mask, key->rtv_active_mask);
}
graphics->dsv_plane_optimal_mask = d3d12_graphics_pipeline_state_get_plane_optimal_mask(graphics, dsv_format);
if (key)
@ -4092,8 +4084,8 @@ static bool d3d12_pipeline_state_can_use_dynamic_stride(struct d3d12_pipeline_st
}
VkPipeline d3d12_pipeline_state_get_pipeline(struct d3d12_pipeline_state *state,
const struct vkd3d_dynamic_state *dyn_state, uint32_t rtv_nonnull_mask,
const struct vkd3d_format *dsv_format, uint32_t *dynamic_state_flags)
const struct vkd3d_dynamic_state *dyn_state, const struct vkd3d_format *dsv_format,
uint32_t *dynamic_state_flags)
{
struct d3d12_graphics_pipeline_state *graphics = &state->graphics;
@ -4112,15 +4104,6 @@ VkPipeline d3d12_pipeline_state_get_pipeline(struct d3d12_pipeline_state *state,
return VK_NULL_HANDLE;
}
/* Case where we render to null or unbound RTV.
* We'll need to nop out the attachments in the render pass / PSO. */
if (state->graphics.rtv_active_mask & ~rtv_nonnull_mask)
{
TRACE("RTV mismatch. Writing to attachment mask 0x%x, but only 0x%x RTVs are bound.\n",
state->graphics.rtv_active_mask, rtv_nonnull_mask);
return VK_NULL_HANDLE;
}
if (!d3d12_pipeline_state_can_use_dynamic_stride(state, dyn_state))
{
TRACE("Cannot use dynamic stride, falling back ...\n");
@ -4145,8 +4128,8 @@ VkPipeline d3d12_pipeline_state_get_pipeline(struct d3d12_pipeline_state *state,
}
VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_state *state,
const struct vkd3d_dynamic_state *dyn_state, uint32_t rtv_nonnull_mask,
const struct vkd3d_format *dsv_format, uint32_t *dynamic_state_flags)
const struct vkd3d_dynamic_state *dyn_state, const struct vkd3d_format *dsv_format,
uint32_t *dynamic_state_flags)
{
const struct vkd3d_vk_device_procs *vk_procs = &state->device->vk_procs;
struct d3d12_graphics_pipeline_state *graphics = &state->graphics;
@ -4189,7 +4172,6 @@ VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_sta
}
pipeline_key.dsv_format = dsv_format ? dsv_format->vk_format : VK_FORMAT_UNDEFINED;
pipeline_key.rtv_active_mask = state->graphics.rtv_active_mask & rtv_nonnull_mask;
if ((vk_pipeline = d3d12_pipeline_state_find_compiled_pipeline(state, &pipeline_key, dynamic_state_flags)))
{

View File

@ -1610,7 +1610,6 @@ struct vkd3d_pipeline_key
D3D12_PRIMITIVE_TOPOLOGY topology;
uint32_t viewport_count;
uint32_t strides[D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
uint32_t rtv_active_mask;
VkFormat dsv_format;
bool dynamic_stride;
@ -1621,11 +1620,11 @@ bool d3d12_pipeline_state_has_replaced_shaders(struct d3d12_pipeline_state *stat
HRESULT d3d12_pipeline_state_create(struct d3d12_device *device, VkPipelineBindPoint bind_point,
const struct d3d12_pipeline_state_desc *desc, struct d3d12_pipeline_state **state);
VkPipeline d3d12_pipeline_state_get_or_create_pipeline(struct d3d12_pipeline_state *state,
const struct vkd3d_dynamic_state *dyn_state, uint32_t rtv_nonnull_mask,
const struct vkd3d_format *dsv_format, uint32_t *dynamic_state_flags);
const struct vkd3d_dynamic_state *dyn_state, const struct vkd3d_format *dsv_format,
uint32_t *dynamic_state_flags);
VkPipeline d3d12_pipeline_state_get_pipeline(struct d3d12_pipeline_state *state,
const struct vkd3d_dynamic_state *dyn_state, uint32_t rtv_nonnull_mask,
const struct vkd3d_format *dsv_format, uint32_t *dynamic_state_flags);
const struct vkd3d_dynamic_state *dyn_state, const struct vkd3d_format *dsv_format,
uint32_t *dynamic_state_flags);
VkPipeline d3d12_pipeline_state_create_pipeline_variant(struct d3d12_pipeline_state *state,
const struct vkd3d_pipeline_key *key, const struct vkd3d_format *dsv_format,
VkPipelineCache vk_cache, uint32_t *dynamic_state_flags);
@ -1975,7 +1974,6 @@ struct d3d12_command_list
struct d3d12_rtv_desc rtvs[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT];
struct d3d12_rtv_desc dsv;
uint32_t rtv_nonnull_mask;
uint32_t dsv_plane_optimal_mask;
VkImageLayout dsv_layout;
unsigned int fb_width;