}
static void
+d3d12_decrement_image_bind_count(struct d3d12_context *ctx,
+ enum pipe_shader_type shader,
+ struct d3d12_resource *res) {
+ assert(res->bind_counts[shader][D3D12_RESOURCE_BINDING_TYPE_IMAGE] > 0);
+ res->bind_counts[shader][D3D12_RESOURCE_BINDING_TYPE_IMAGE]--;
+}
+
+static void
+d3d12_increment_image_bind_count(struct d3d12_context *ctx,
+ enum pipe_shader_type shader,
+ struct d3d12_resource *res) {
+ res->bind_counts[shader][D3D12_RESOURCE_BINDING_TYPE_IMAGE]++;
+}
+
+static void
+d3d12_set_shader_images(struct pipe_context *pctx,
+ enum pipe_shader_type shader,
+ unsigned start_slot, unsigned count,
+ unsigned unbind_num_trailing_slots,
+ const struct pipe_image_view *images)
+{
+ struct d3d12_context *ctx = d3d12_context(pctx);
+ for (unsigned i = 0; i < count + unbind_num_trailing_slots; ++i) {
+ struct pipe_image_view *slot = &ctx->image_views[shader][i + start_slot];
+ if (slot->resource) {
+ d3d12_decrement_image_bind_count(ctx, shader, d3d12_resource(slot->resource));
+ pipe_resource_reference(&slot->resource, NULL);
+ }
+
+ if (i < count && images && images[i].resource) {
+ pipe_resource_reference(&slot->resource, images[i].resource);
+ *slot = images[i];
+ d3d12_increment_image_bind_count(ctx, shader, d3d12_resource(images[i].resource));
+ } else
+ memset(slot, 0, sizeof(*slot));
+ }
+
+ if (images) {
+ ctx->num_image_views[shader] = MAX2(ctx->num_image_views[shader], count + start_slot);
+ } else {
+ ctx->num_image_views[shader] = 0;
+ for (int i = start_slot + count - 1; i >= (int)start_slot; --i) {
+ if (ctx->image_views[shader][i].resource) {
+ ctx->num_image_views[shader] = i;
+ break;
+ }
+ }
+ }
+ ctx->shader_dirty[shader] |= D3D12_SHADER_DIRTY_IMAGE;
+}
+
+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, SRV, or UAV
// set the context shader_dirty bit.
if (res->bind_counts[i][D3D12_RESOURCE_BINDING_TYPE_SSBO] > 0) {
ctx->shader_dirty[i] |= D3D12_SHADER_DIRTY_SSBO;
}
+
+ if (res->bind_counts[i][D3D12_RESOURCE_BINDING_TYPE_IMAGE] > 0) {
+ ctx->shader_dirty[i] |= D3D12_SHADER_DIRTY_IMAGE;
+ }
}
}
ctx->base.set_stream_output_targets = d3d12_set_stream_output_targets;
ctx->base.set_shader_buffers = d3d12_set_shader_buffers;
+ ctx->base.set_shader_images = d3d12_set_shader_images;
ctx->base.get_timestamp = d3d12_get_timestamp;
D3D12_SHADER_DIRTY_SAMPLER_VIEWS = (1 << 1),
D3D12_SHADER_DIRTY_SAMPLERS = (1 << 2),
D3D12_SHADER_DIRTY_SSBO = (1 << 3),
+ D3D12_SHADER_DIRTY_IMAGE = (1 << 4),
};
#define D3D12_DIRTY_PSO (D3D12_DIRTY_BLEND | D3D12_DIRTY_RASTERIZER | D3D12_DIRTY_ZSA | \
D3D12_DIRTY_STRIP_CUT_VALUE)
#define D3D12_SHADER_DIRTY_ALL (D3D12_SHADER_DIRTY_CONSTBUF | D3D12_SHADER_DIRTY_SAMPLER_VIEWS | \
- D3D12_SHADER_DIRTY_SAMPLERS | D3D12_SHADER_DIRTY_SSBO)
+ D3D12_SHADER_DIRTY_SAMPLERS | D3D12_SHADER_DIRTY_SSBO | \
+ D3D12_SHADER_DIRTY_IMAGE)
enum d3d12_binding_type {
D3D12_BINDING_CONSTANT_BUFFER,
D3D12_BINDING_SAMPLER,
D3D12_BINDING_STATE_VARS,
D3D12_BINDING_SSBO,
+ D3D12_BINDING_IMAGE,
D3D12_NUM_BINDING_TYPES
};
unsigned has_int_samplers;
struct pipe_shader_buffer ssbo_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_BUFFERS];
unsigned num_ssbo_views[PIPE_SHADER_TYPES];
+ struct pipe_image_view image_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_IMAGES];
+ unsigned num_image_views[PIPE_SHADER_TYPES];
struct d3d12_sampler_state *samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
unsigned num_samplers[PIPE_SHADER_TYPES];
D3D12_INDEX_BUFFER_VIEW ibv;