vkd3d: Properly invalidate pipeline when binding NULL DSV.
We did not test the scenario where we first render with depth enabled, and then bind a NULL DSV with the same pipeline. Also fix issues if we bind NULL RTVs with same pipeline bound. Fixes crash in Guardians of the Galaxy. Signed-off-by: Hans-Kristian Arntzen <post@arntzen-software.no>
This commit is contained in:
parent
5e526d506b
commit
1d39c25a59
|
@ -4438,14 +4438,19 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearState(d3d12_command_list_i
|
|||
d3d12_command_list_reset_api_state(list, pipeline_state);
|
||||
}
|
||||
|
||||
static bool d3d12_graphics_pipeline_state_is_depth_stencil_sensitive(const struct d3d12_graphics_pipeline_state *graphics)
|
||||
{
|
||||
return graphics->dsv_format || d3d12_graphics_pipeline_state_has_unknown_dsv_format(graphics);
|
||||
}
|
||||
|
||||
static bool d3d12_command_list_has_depth_stencil_view(struct d3d12_command_list *list)
|
||||
{
|
||||
struct d3d12_graphics_pipeline_state *graphics;
|
||||
const struct d3d12_graphics_pipeline_state *graphics;
|
||||
|
||||
assert(d3d12_pipeline_state_is_graphics(list->state));
|
||||
graphics = &list->state->graphics;
|
||||
|
||||
return list->dsv.format && (graphics->dsv_format || d3d12_pipeline_state_has_unknown_dsv_format(list->state));
|
||||
return list->dsv.format && (graphics->dsv_format || d3d12_graphics_pipeline_state_has_unknown_dsv_format(graphics));
|
||||
}
|
||||
|
||||
static void d3d12_command_list_get_fb_extent(struct d3d12_command_list *list,
|
||||
|
@ -7930,8 +7935,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(d3d12_comman
|
|||
{
|
||||
struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface);
|
||||
const VkPhysicalDeviceLimits *limits = &list->device->vk_info.device_limits;
|
||||
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, "
|
||||
|
@ -7961,6 +7968,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(d3d12_comman
|
|||
/* Need to deduce DSV layouts again. */
|
||||
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)
|
||||
|
@ -8009,8 +8018,17 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(d3d12_comman
|
|||
}
|
||||
}
|
||||
|
||||
if (prev_dsv_format != next_dsv_format && d3d12_pipeline_state_has_unknown_dsv_format(list->state))
|
||||
d3d12_command_list_invalidate_current_pipeline(list, false);
|
||||
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 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. */
|
||||
d3d12_command_list_invalidate_current_pipeline(list, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool d3d12_rect_fully_covers_region(const D3D12_RECT *a, const D3D12_RECT *b)
|
||||
|
|
|
@ -1537,16 +1537,10 @@ static inline bool d3d12_pipeline_state_is_graphics(const struct d3d12_pipeline_
|
|||
return state && state->vk_bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
}
|
||||
|
||||
static inline bool d3d12_pipeline_state_has_unknown_dsv_format(struct d3d12_pipeline_state *state)
|
||||
static inline bool d3d12_graphics_pipeline_state_has_unknown_dsv_format(
|
||||
const struct d3d12_graphics_pipeline_state *graphics)
|
||||
{
|
||||
if (d3d12_pipeline_state_is_graphics(state))
|
||||
{
|
||||
struct d3d12_graphics_pipeline_state *graphics = &state->graphics;
|
||||
|
||||
return graphics->null_attachment_mask & dsv_attachment_mask(graphics);
|
||||
}
|
||||
|
||||
return false;
|
||||
return graphics->null_attachment_mask & dsv_attachment_mask(graphics);
|
||||
}
|
||||
|
||||
struct d3d12_cached_pipeline_state
|
||||
|
|
Loading…
Reference in New Issue