Module: Mesa
Branch: main
Commit: bb1d0025d893b681aef230101711b9aad860f956
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=bb1d0025d893b681aef230101711b9aad860f956

Author: BillKristiansen <[email protected]>
Date:   Tue May 18 10:56:31 2021 -0700

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>

---

 src/gallium/drivers/d3d12/d3d12_blit.cpp     |  19 +++--
 src/gallium/drivers/d3d12/d3d12_context.cpp  | 105 +++++++++++++++++++++++----
 src/gallium/drivers/d3d12/d3d12_context.h    |  11 ++-
 src/gallium/drivers/d3d12/d3d12_draw.cpp     |  19 +++--
 src/gallium/drivers/d3d12/d3d12_query.cpp    |   8 +-
 src/gallium/drivers/d3d12/d3d12_resource.cpp |  11 +--
 src/gallium/drivers/d3d12/d3d12_resource.h   |   7 ++
 7 files changed, 140 insertions(+), 40 deletions(-)

diff --git a/src/gallium/drivers/d3d12/d3d12_blit.cpp 
b/src/gallium/drivers/d3d12/d3d12_blit.cpp
index 476b12c23d3..d130476ac51 100644
--- a/src/gallium/drivers/d3d12/d3d12_blit.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_blit.cpp
@@ -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);
diff --git a/src/gallium/drivers/d3d12/d3d12_context.cpp 
b/src/gallium/drivers/d3d12/d3d12_context.cpp
index 11156bf0abf..aa51a953f88 100644
--- a/src/gallium/drivers/d3d12/d3d12_context.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_context.cpp
@@ -919,6 +919,26 @@ d3d12_create_sampler_view(struct pipe_context *pctx,
    return &sampler_view->base;
 }
 
+static void
+d3d12_increment_sampler_view_bind_count(struct pipe_context *ctx,
+   enum pipe_shader_type shader_type,
+   struct pipe_sampler_view *view) {
+      struct d3d12_resource *res = d3d12_resource(view->texture);
+      if (res)
+         res->bind_counts[shader_type][D3D12_RESOURCE_BINDING_TYPE_SRV]++;
+}
+
+static void
+d3d12_decrement_sampler_view_bind_count(struct pipe_context *ctx,
+                              enum pipe_shader_type shader_type,
+                              struct pipe_sampler_view *view) {
+   struct d3d12_resource *res = d3d12_resource(view->texture);
+   if (res) {
+      assert(res->bind_counts[shader_type][D3D12_RESOURCE_BINDING_TYPE_SRV] > 
0);
+      res->bind_counts[shader_type][D3D12_RESOURCE_BINDING_TYPE_SRV]--;
+   }
+}
+
 static void
 d3d12_set_sampler_views(struct pipe_context *pctx,
                         enum pipe_shader_type shader_type,
@@ -932,9 +952,15 @@ d3d12_set_sampler_views(struct pipe_context *pctx,
    ctx->has_int_samplers &= ~shader_bit;
 
    for (unsigned i = 0; i < num_views; ++i) {
-      pipe_sampler_view_reference(
-         &ctx->sampler_views[shader_type][start_slot + i],
-         views[i]);
+      struct pipe_sampler_view *&old_view = 
ctx->sampler_views[shader_type][start_slot + i];
+      if (old_view)
+         d3d12_decrement_sampler_view_bind_count(pctx, shader_type, old_view);
+
+      struct pipe_sampler_view *new_view = views[i];
+      if (new_view)
+         d3d12_increment_sampler_view_bind_count(pctx, shader_type, new_view);
+
+      pipe_sampler_view_reference(&old_view, views[i]);
 
       if (views[i]) {
          dxil_wrap_sampler_state &wss = 
ctx->tex_wrap_states[shader_type][start_slot + i];
@@ -965,10 +991,12 @@ d3d12_set_sampler_views(struct pipe_context *pctx,
       }
    }
 
-   for (unsigned i = 0; i < unbind_num_trailing_slots; i++)
-      pipe_sampler_view_reference(
-         &ctx->sampler_views[shader_type][start_slot + num_views + i], NULL);
-
+   for (unsigned i = 0; i < unbind_num_trailing_slots; i++) {
+      struct pipe_sampler_view *&old_view = 
ctx->sampler_views[shader_type][start_slot + num_views + i];
+      if (old_view)
+         d3d12_decrement_sampler_view_bind_count(pctx, shader_type, old_view);
+      pipe_sampler_view_reference(&old_view, NULL);
+   }
    ctx->num_sampler_views[shader_type] = start_slot + num_views;
    ctx->shader_dirty[shader_type] |= D3D12_SHADER_DIRTY_SAMPLER_VIEWS;
 }
@@ -1201,6 +1229,21 @@ d3d12_set_scissor_states(struct pipe_context *pctx,
    ctx->state_dirty |= D3D12_DIRTY_SCISSOR;
 }
 
+static void
+d3d12_decrement_constant_buffer_bind_count(struct d3d12_context *ctx,
+                                           enum pipe_shader_type shader,
+                                           struct d3d12_resource *res) {
+   assert(res->bind_counts[shader][D3D12_RESOURCE_BINDING_TYPE_CBV] > 0);
+   res->bind_counts[shader][D3D12_RESOURCE_BINDING_TYPE_CBV]--;
+}
+
+static void
+d3d12_increment_constant_buffer_bind_count(struct d3d12_context *ctx,
+                                           enum pipe_shader_type shader,
+                                           struct d3d12_resource *res) {
+   res->bind_counts[shader][D3D12_RESOURCE_BINDING_TYPE_CBV]++;
+}
+
 static void
 d3d12_set_constant_buffer(struct pipe_context *pctx,
                           enum pipe_shader_type shader, uint index,
@@ -1219,8 +1262,13 @@ d3d12_set_constant_buffer(struct pipe_context *pctx,
 
       } else {
          if (take_ownership) {
+            struct d3d12_resource *old_buf = 
d3d12_resource(ctx->cbufs[shader][index].buffer);
+            if (old_buf)
+               d3d12_decrement_constant_buffer_bind_count(ctx, shader, 
old_buf);
             pipe_resource_reference(&ctx->cbufs[shader][index].buffer, NULL);
             ctx->cbufs[shader][index].buffer = buffer;
+            if (buffer)
+               d3d12_increment_constant_buffer_bind_count(ctx, shader, 
d3d12_resource(buffer));
          } else {
             pipe_resource_reference(&ctx->cbufs[shader][index].buffer, buffer);
          }
@@ -1389,6 +1437,21 @@ d3d12_set_stream_output_targets(struct pipe_context 
*pctx,
    ctx->state_dirty |= D3D12_DIRTY_STREAM_OUTPUT;
 }
 
+static void
+d3d12_invalidate_context_bindings(struct d3d12_context *ctx, struct 
d3d12_resource *res) {
+   // For each shader type, if the resource is currently bound as CBV or SRV
+   // set the context shader_dirty bit.
+   for (uint i = 0; i < PIPE_SHADER_TYPES; ++i) {
+      if (res->bind_counts[i][D3D12_RESOURCE_BINDING_TYPE_CBV] > 0) {
+         ctx->shader_dirty[i] |= D3D12_SHADER_DIRTY_CONSTBUF;
+      }
+
+      if (res->bind_counts[i][D3D12_RESOURCE_BINDING_TYPE_SRV] > 0) {
+         ctx->shader_dirty[i] |= D3D12_SHADER_DIRTY_SAMPLER_VIEWS;
+      }
+   }
+}
+
 bool
 d3d12_enable_fake_so_buffers(struct d3d12_context *ctx, unsigned factor)
 {
@@ -1532,9 +1595,14 @@ d3d12_flush_cmdlist_and_wait(struct d3d12_context *ctx)
 void
 d3d12_transition_resource_state(struct d3d12_context *ctx,
                                 struct d3d12_resource *res,
-                                D3D12_RESOURCE_STATES state)
+                                D3D12_RESOURCE_STATES state,
+                                d3d12_bind_invalidate_option bind_invalidate)
 {
    TransitionableResourceState *xres = d3d12_resource_state(res);
+   
+   if (bind_invalidate == D3D12_BIND_INVALIDATE_FULL)
+      d3d12_invalidate_context_bindings(ctx, res);
+
    ctx->resource_state_manager->TransitionResource(xres, state);
 }
 
@@ -1544,10 +1612,14 @@ d3d12_transition_subresources_state(struct 
d3d12_context *ctx,
                                     uint32_t start_level, uint32_t num_levels,
                                     uint32_t start_layer, uint32_t num_layers,
                                     uint32_t start_plane, uint32_t num_planes,
-                                    D3D12_RESOURCE_STATES state)
+                                    D3D12_RESOURCE_STATES state,
+                                    d3d12_bind_invalidate_option 
bind_invalidate)
 {
    TransitionableResourceState *xres = d3d12_resource_state(res);
 
+   if(bind_invalidate == D3D12_BIND_INVALIDATE_FULL)
+      d3d12_invalidate_context_bindings(ctx, res);
+
    for (uint32_t l = 0; l < num_levels; l++) {
       const uint32_t level = start_level + l;
       for (uint32_t a = 0; a < num_layers; a++) {
@@ -1582,8 +1654,10 @@ d3d12_clear_render_target(struct pipe_context *pctx,
    if (!render_condition_enabled && ctx->current_predication)
       ctx->cmdlist->SetPredication(NULL, 0, D3D12_PREDICATION_OP_EQUAL_ZERO);
 
-   d3d12_transition_resource_state(ctx, d3d12_resource(psurf->texture),
-                                   D3D12_RESOURCE_STATE_RENDER_TARGET);
+   struct d3d12_resource *res = d3d12_resource(psurf->texture);
+   d3d12_transition_resource_state(ctx, res,
+                                   D3D12_RESOURCE_STATE_RENDER_TARGET,
+                                   D3D12_BIND_INVALIDATE_FULL);
    d3d12_apply_resource_states(ctx);
 
    enum pipe_format format = psurf->texture->format;
@@ -1637,8 +1711,10 @@ d3d12_clear_depth_stencil(struct pipe_context *pctx,
    if (clear_flags & PIPE_CLEAR_STENCIL)
       flags |= D3D12_CLEAR_FLAG_STENCIL;
 
-   d3d12_transition_resource_state(ctx, d3d12_resource(ctx->fb.zsbuf->texture),
-                                   D3D12_RESOURCE_STATE_DEPTH_WRITE);
+   struct d3d12_resource *res = d3d12_resource(ctx->fb.zsbuf->texture);
+   d3d12_transition_resource_state(ctx, res,
+                                   D3D12_RESOURCE_STATE_DEPTH_WRITE,
+                                   D3D12_BIND_INVALIDATE_FULL);
    d3d12_apply_resource_states(ctx);
 
    D3D12_RECT rect = { (int)dstx, (int)dsty,
@@ -1708,7 +1784,8 @@ d3d12_flush_resource(struct pipe_context *pctx,
    struct d3d12_resource *res = d3d12_resource(pres);
 
    d3d12_transition_resource_state(ctx, res,
-                                   D3D12_RESOURCE_STATE_COMMON);
+                                   D3D12_RESOURCE_STATE_COMMON,
+                                   D3D12_BIND_INVALIDATE_FULL);
    d3d12_apply_resource_states(ctx);
 }
 
diff --git a/src/gallium/drivers/d3d12/d3d12_context.h 
b/src/gallium/drivers/d3d12/d3d12_context.h
index d280bb4b904..362b8022278 100644
--- a/src/gallium/drivers/d3d12/d3d12_context.h
+++ b/src/gallium/drivers/d3d12/d3d12_context.h
@@ -271,10 +271,16 @@ void
 d3d12_flush_cmdlist_and_wait(struct d3d12_context *ctx);
 
 
+enum d3d12_bind_invalidate_option {
+   D3D12_BIND_INVALIDATE_NONE,
+   D3D12_BIND_INVALIDATE_FULL,
+};
+
 void
 d3d12_transition_resource_state(struct d3d12_context* ctx,
                                 struct d3d12_resource* res,
-                                D3D12_RESOURCE_STATES state);
+                                D3D12_RESOURCE_STATES state,
+                                d3d12_bind_invalidate_option bind_invalidate);
 
 void
 d3d12_transition_subresources_state(struct d3d12_context *ctx,
@@ -282,7 +288,8 @@ d3d12_transition_subresources_state(struct d3d12_context 
*ctx,
                                     unsigned start_level, unsigned num_levels,
                                     unsigned start_layer, unsigned num_layers,
                                     unsigned start_plane, unsigned num_planes,
-                                    D3D12_RESOURCE_STATES state);
+                                    D3D12_RESOURCE_STATES state,
+                                    d3d12_bind_invalidate_option 
bind_invalidate);
 
 void
 d3d12_apply_resource_states(struct d3d12_context* ctx);
diff --git a/src/gallium/drivers/d3d12/d3d12_draw.cpp 
b/src/gallium/drivers/d3d12/d3d12_draw.cpp
index 45ff9655815..c4efa7bd87e 100644
--- a/src/gallium/drivers/d3d12/d3d12_draw.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_draw.cpp
@@ -63,7 +63,7 @@ fill_cbv_descriptors(struct d3d12_context *ctx,
       D3D12_CONSTANT_BUFFER_VIEW_DESC cbv_desc = {};
       if (buffer && buffer->buffer) {
          struct d3d12_resource *res = d3d12_resource(buffer->buffer);
-         d3d12_transition_resource_state(ctx, res, 
D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
+         d3d12_transition_resource_state(ctx, res, 
D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, D3D12_BIND_INVALIDATE_NONE);
          cbv_desc.BufferLocation = d3d12_resource_gpu_virtual_address(res) + 
buffer->buffer_offset;
          cbv_desc.SizeInBytes = MIN2(D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * 
16,
             align(buffer->buffer_size, 256));
@@ -110,14 +110,16 @@ fill_srv_descriptors(struct d3d12_context *ctx,
                                        
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;
          if (view->base.texture->target == PIPE_BUFFER) {
             d3d12_transition_resource_state(ctx, 
d3d12_resource(view->base.texture),
-                                            state);
+                                            state,
+                                            D3D12_BIND_INVALIDATE_NONE);
          } else {
             d3d12_transition_subresources_state(ctx, 
d3d12_resource(view->base.texture),
                                                 view->base.u.tex.first_level, 
view->mip_levels,
                                                 view->base.u.tex.first_layer, 
view->array_size,
                                                 
d3d12_get_format_start_plane(view->base.format),
                                                 
d3d12_get_format_num_planes(view->base.format),
-                                                state);
+                                                state,
+                                                D3D12_BIND_INVALIDATE_NONE);
          }
       } else {
          descs[desc_idx] = 
screen->null_srvs[shader->srv_bindings[i].dimension].cpu_handle;
@@ -388,7 +390,8 @@ transition_surface_subresources_state(struct d3d12_context 
*ctx,
                                        start_layer, num_layers,
                                        
d3d12_get_format_start_plane(psurf->format),
                                        
d3d12_get_format_num_planes(psurf->format),
-                                       state);
+                                       state,
+                                       D3D12_BIND_INVALIDATE_FULL);
 }
 
 static bool
@@ -625,7 +628,7 @@ d3d12_draw_vbo(struct pipe_context *pctx,
    for (unsigned i = 0; i < ctx->num_vbs; ++i) {
       if (ctx->vbs[i].buffer.resource) {
          struct d3d12_resource *res = 
d3d12_resource(ctx->vbs[i].buffer.resource);
-         d3d12_transition_resource_state(ctx, res, 
D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER);
+         d3d12_transition_resource_state(ctx, res, 
D3D12_RESOURCE_STATE_VERTEX_AND_CONSTANT_BUFFER, D3D12_BIND_INVALIDATE_NONE);
          if (ctx->cmdlist_dirty & D3D12_DIRTY_VERTEX_BUFFERS)
             d3d12_batch_reference_resource(batch, res);
       }
@@ -639,7 +642,7 @@ d3d12_draw_vbo(struct pipe_context *pctx,
       ibv.BufferLocation = d3d12_resource_gpu_virtual_address(res) + 
index_offset;
       ibv.SizeInBytes = res->base.width0 - index_offset;
       ibv.Format = ib_format(dinfo->index_size);
-      d3d12_transition_resource_state(ctx, res, 
D3D12_RESOURCE_STATE_INDEX_BUFFER);
+      d3d12_transition_resource_state(ctx, res, 
D3D12_RESOURCE_STATE_INDEX_BUFFER, D3D12_BIND_INVALIDATE_NONE);
       if (ctx->cmdlist_dirty & D3D12_DIRTY_INDEX_BUFFER ||
           memcmp(&ctx->ibv, &ibv, sizeof(D3D12_INDEX_BUFFER_VIEW)) != 0) {
          ctx->ibv = ibv;
@@ -691,8 +694,8 @@ d3d12_draw_vbo(struct pipe_context *pctx,
          d3d12_batch_reference_resource(batch, fill_buffer);
       }
 
-      d3d12_transition_resource_state(ctx, so_buffer, 
D3D12_RESOURCE_STATE_STREAM_OUT);
-      d3d12_transition_resource_state(ctx, fill_buffer, 
D3D12_RESOURCE_STATE_STREAM_OUT);
+      d3d12_transition_resource_state(ctx, so_buffer, 
D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_BIND_INVALIDATE_NONE);
+      d3d12_transition_resource_state(ctx, fill_buffer, 
D3D12_RESOURCE_STATE_STREAM_OUT, D3D12_BIND_INVALIDATE_NONE);
    }
    if (ctx->cmdlist_dirty & D3D12_DIRTY_STREAM_OUTPUT)
       ctx->cmdlist->SOSetTargets(0, 4, so_buffer_views);
diff --git a/src/gallium/drivers/d3d12/d3d12_query.cpp 
b/src/gallium/drivers/d3d12/d3d12_query.cpp
index c1f10679049..0463d13f856 100644
--- a/src/gallium/drivers/d3d12/d3d12_query.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_query.cpp
@@ -367,7 +367,7 @@ end_query(struct d3d12_context *ctx, struct d3d12_query *q)
 
    offset += q->buffer_offset + resolve_index * q->query_size;
    ctx->cmdlist->EndQuery(q->query_heap, q->d3d12qtype, end_index);
-   d3d12_transition_resource_state(ctx, res, D3D12_RESOURCE_STATE_COPY_DEST);
+   d3d12_transition_resource_state(ctx, res, D3D12_RESOURCE_STATE_COPY_DEST, 
D3D12_BIND_INVALIDATE_FULL);
    d3d12_apply_resource_states(ctx);
    ctx->cmdlist->ResolveQueryData(q->query_heap, q->d3d12qtype, resolve_index,
                                   resolve_count, d3d12_res, offset);
@@ -483,14 +483,14 @@ d3d12_render_condition(struct pipe_context *pctx,
    }
 
    struct d3d12_resource *res = (struct d3d12_resource *)query->buffer;
-   d3d12_transition_resource_state(ctx, res, D3D12_RESOURCE_STATE_COPY_SOURCE);
-   d3d12_transition_resource_state(ctx, query->predicate, 
D3D12_RESOURCE_STATE_COPY_DEST);
+   d3d12_transition_resource_state(ctx, res, D3D12_RESOURCE_STATE_COPY_SOURCE, 
D3D12_BIND_INVALIDATE_FULL);
+   d3d12_transition_resource_state(ctx, query->predicate, 
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_BIND_INVALIDATE_NONE);
    d3d12_apply_resource_states(ctx);
    ctx->cmdlist->CopyBufferRegion(d3d12_resource_resource(query->predicate), 0,
                                   d3d12_resource_resource(res), 0,
                                   sizeof(uint64_t));
 
-   d3d12_transition_resource_state(ctx, query->predicate, 
D3D12_RESOURCE_STATE_PREDICATION);
+   d3d12_transition_resource_state(ctx, query->predicate, 
D3D12_RESOURCE_STATE_PREDICATION, D3D12_BIND_INVALIDATE_NONE);
    d3d12_apply_resource_states(ctx);
 
    ctx->current_predication = query->predicate;
diff --git a/src/gallium/drivers/d3d12/d3d12_resource.cpp 
b/src/gallium/drivers/d3d12/d3d12_resource.cpp
index ac93ed33a5d..2b06b37c3c1 100644
--- a/src/gallium/drivers/d3d12/d3d12_resource.cpp
+++ b/src/gallium/drivers/d3d12/d3d12_resource.cpp
@@ -277,6 +277,8 @@ d3d12_resource_create(struct pipe_screen *pscreen,
 
    init_valid_range(res);
 
+   memset(&res->bind_counts, 0, sizeof(d3d12_resource::bind_counts));
+
    return &res->base;
 }
 
@@ -413,9 +415,8 @@ copy_texture_region(struct d3d12_context *ctx,
 
    d3d12_batch_reference_resource(batch, info.src);
    d3d12_batch_reference_resource(batch, info.dst);
-
-   d3d12_transition_resource_state(ctx, info.src, 
D3D12_RESOURCE_STATE_COPY_SOURCE);
-   d3d12_transition_resource_state(ctx, info.dst, 
D3D12_RESOURCE_STATE_COPY_DEST);
+   d3d12_transition_resource_state(ctx, info.src, 
D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_BIND_INVALIDATE_FULL);
+   d3d12_transition_resource_state(ctx, info.dst, 
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_BIND_INVALIDATE_FULL);
    d3d12_apply_resource_states(ctx);
    ctx->cmdlist->CopyTextureRegion(&info.dst_loc, info.dst_x, info.dst_y, 
info.dst_z,
                                    &info.src_loc, info.src_box);
@@ -593,8 +594,8 @@ transfer_buf_to_buf(struct d3d12_context *ctx,
 
    // Same-resource copies not supported, since the resource would need to be 
in both states
    assert(src_d3d12 != dst_d3d12);
-   d3d12_transition_resource_state(ctx, src, D3D12_RESOURCE_STATE_COPY_SOURCE);
-   d3d12_transition_resource_state(ctx, dst, D3D12_RESOURCE_STATE_COPY_DEST);
+   d3d12_transition_resource_state(ctx, src, D3D12_RESOURCE_STATE_COPY_SOURCE, 
D3D12_BIND_INVALIDATE_FULL);
+   d3d12_transition_resource_state(ctx, dst, D3D12_RESOURCE_STATE_COPY_DEST, 
D3D12_BIND_INVALIDATE_FULL);
    d3d12_apply_resource_states(ctx);
    ctx->cmdlist->CopyBufferRegion(dst_d3d12, dst_offset,
                                   src_d3d12, src_offset,
diff --git a/src/gallium/drivers/d3d12/d3d12_resource.h 
b/src/gallium/drivers/d3d12/d3d12_resource.h
index 4c8dccb02e9..a71c8206f44 100644
--- a/src/gallium/drivers/d3d12/d3d12_resource.h
+++ b/src/gallium/drivers/d3d12/d3d12_resource.h
@@ -31,6 +31,12 @@ struct pipe_screen;
 
 #include <directx/d3d12.h>
 
+enum d3d12_resource_binding_type {
+   D3D12_RESOURCE_BINDING_TYPE_SRV,
+   D3D12_RESOURCE_BINDING_TYPE_CBV,
+   D3D12_RESOURCE_BINDING_TYPES
+};
+
 struct d3d12_resource {
    struct pipe_resource base;
    struct d3d12_bo *bo;
@@ -39,6 +45,7 @@ struct d3d12_resource {
    struct sw_displaytarget *dt;
    unsigned dt_stride;
    struct util_range valid_buffer_range;
+   uint32_t bind_counts[PIPE_SHADER_TYPES][D3D12_RESOURCE_BINDING_TYPES];
 };
 
 struct d3d12_transfer {

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to