d3d12: Fixes stale context bindings after copy, resolve, and clear

Some GL applications, including Blender, are producing rendering
artifacts due to missing resource state barriers.

The d3d12_context keeps track of all resources bound as shader resource
or constant buffers.  If any of these resources are used for Copy,
Resolve, or Clear source/target, the context tracking must be updated
so the correct state can be restored before the next draw call.

This change is something of a big hammer.  Essentially, if a resource
currently bound as an SRV or CBV gets used for a non-shader access, a
flag is set in the context that invalidates all bindings of the same
type on the same shader stage.  Thus the next Draw execution refreshes
the shader views and state transitions state before invoking Draw on the
command list.

A more elegant (and complex) fix would limit the invalidation to
resource state only, rather than also forcing a recreation of resource
views.  It is unclear right now whether it is worth the time to
implement a more elegant fix.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10871>
This commit is contained in:
BillKristiansen
2021-05-18 10:56:31 -07:00
committed by Marge Bot
parent 59c22727bb
commit bb1d0025d8
7 changed files with 140 additions and 40 deletions

View File

@@ -115,9 +115,11 @@ blit_resolve(struct d3d12_context *ctx, const struct pipe_blit_info *info)
struct d3d12_resource *dst = d3d12_resource(info->dst.resource);
d3d12_transition_resource_state(ctx, src,
D3D12_RESOURCE_STATE_RESOLVE_SOURCE);
D3D12_RESOURCE_STATE_RESOLVE_SOURCE,
D3D12_BIND_INVALIDATE_FULL);
d3d12_transition_resource_state(ctx, dst,
D3D12_RESOURCE_STATE_RESOLVE_DEST);
D3D12_RESOURCE_STATE_RESOLVE_DEST,
D3D12_BIND_INVALIDATE_FULL);
d3d12_apply_resource_states(ctx);
@@ -418,16 +420,17 @@ d3d12_direct_copy(struct d3d12_context *ctx,
debug_printf("BLIT: Direct copy from subres %d to subres %d\n",
src_subres, dst_subres);
d3d12_transition_subresources_state(ctx, src, src_subres, 1, 0, 1,
d3d12_get_format_start_plane(src->base.format),
d3d12_get_format_num_planes(src->base.format),
D3D12_RESOURCE_STATE_COPY_SOURCE);
D3D12_RESOURCE_STATE_COPY_SOURCE,
D3D12_BIND_INVALIDATE_FULL);
d3d12_transition_subresources_state(ctx, dst, dst_subres, 1, 0, 1,
d3d12_get_format_start_plane(dst->base.format),
d3d12_get_format_num_planes(dst->base.format),
D3D12_RESOURCE_STATE_COPY_DEST);
D3D12_RESOURCE_STATE_COPY_DEST,
D3D12_BIND_INVALIDATE_FULL);
d3d12_apply_resource_states(ctx);
@@ -815,10 +818,12 @@ blit_resolve_stencil(struct d3d12_context *ctx,
struct d3d12_resource *dst = d3d12_resource(info->dst.resource);
d3d12_transition_subresources_state(ctx, d3d12_resource(tmp),
0, 1, 0, 1, 0, 1,
D3D12_RESOURCE_STATE_COPY_SOURCE);
D3D12_RESOURCE_STATE_COPY_SOURCE,
D3D12_BIND_INVALIDATE_NONE);
d3d12_transition_subresources_state(ctx, dst,
0, 1, 0, 1, 1, 1,
D3D12_RESOURCE_STATE_COPY_DEST);
D3D12_RESOURCE_STATE_COPY_DEST,
D3D12_BIND_INVALIDATE_FULL);
d3d12_apply_resource_states(ctx);
struct d3d12_batch *batch = d3d12_current_batch(ctx);