diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c index 3d57545b..79894016 100644 --- a/libs/vkd3d/command.c +++ b/libs/vkd3d/command.c @@ -2835,22 +2835,26 @@ static void STDMETHODCALLTYPE d3d12_command_list_SetPipelineState(ID3D12Graphics { struct d3d12_pipeline_state *state = unsafe_impl_from_ID3D12PipelineState(pipeline_state); struct d3d12_command_list *list = impl_from_ID3D12GraphicsCommandList(iface); + const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; TRACE("iface %p, pipeline_state %p.\n", iface, pipeline_state); - list->state = state; d3d12_command_list_invalidate_bindings(list, state); if (d3d12_pipeline_state_is_compute(state)) { - const struct vkd3d_vk_device_procs *vk_procs = &list->device->vk_procs; VK_CALL(vkCmdBindPipeline(list->vk_command_buffer, state->vk_bind_point, state->u.compute.vk_pipeline)); } else { - d3d12_command_list_invalidate_current_framebuffer(list); + if (!d3d12_pipeline_state_is_render_pass_compatible(list->state, state)) + { + d3d12_command_list_invalidate_current_framebuffer(list); + } d3d12_command_list_invalidate_current_pipeline(list); } + + list->state = state; } static void STDMETHODCALLTYPE d3d12_command_list_ResourceBarrier(ID3D12GraphicsCommandList *iface, diff --git a/libs/vkd3d/state.c b/libs/vkd3d/state.c index 8b10a626..43b1c157 100644 --- a/libs/vkd3d/state.c +++ b/libs/vkd3d/state.c @@ -1798,6 +1798,40 @@ static unsigned int vkd3d_get_rt_format_swizzle(const struct vkd3d_format *forma return VKD3D_NO_SWIZZLE; } +/* + * This must return results in accordance with render passes created by + * d3d12_pipeline_state_init_graphics(). + */ +bool d3d12_pipeline_state_is_render_pass_compatible(const struct d3d12_pipeline_state *state_a, + const struct d3d12_pipeline_state *state_b) +{ + const struct d3d12_graphics_pipeline_state *a = &state_a->u.graphics; + const struct d3d12_graphics_pipeline_state *b = &state_b->u.graphics; + unsigned int i; + + if (!state_a != !state_b) + return false; + if (!state_a && !state_b) + return true; + + if (state_a->vk_bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS + || state_b->vk_bind_point != VK_PIPELINE_BIND_POINT_GRAPHICS) + return false; + + if (a->rt_idx != b->rt_idx) + return false; + if (a->attachment_count != b->attachment_count) + return false; + + for (i = 0; i < a->attachment_count; ++i) + { + if (a->attachments[i].format != b->attachments[i].format) + return false; + } + + return true; +} + static HRESULT d3d12_pipeline_state_init_graphics(struct d3d12_pipeline_state *state, struct d3d12_device *device, const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc) { diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 59741684..9fa29fb5 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -525,6 +525,8 @@ HRESULT d3d12_pipeline_state_create_compute(struct d3d12_device *device, const D3D12_COMPUTE_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state) DECLSPEC_HIDDEN; HRESULT d3d12_pipeline_state_create_graphics(struct d3d12_device *device, const D3D12_GRAPHICS_PIPELINE_STATE_DESC *desc, struct d3d12_pipeline_state **state) DECLSPEC_HIDDEN; +bool d3d12_pipeline_state_is_render_pass_compatible(const struct d3d12_pipeline_state *state_a, + const struct d3d12_pipeline_state *state_b) DECLSPEC_HIDDEN; struct d3d12_pipeline_state *unsafe_impl_from_ID3D12PipelineState(ID3D12PipelineState *iface) DECLSPEC_HIDDEN; struct vkd3d_buffer