mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 00:58:05 +02:00
d3d12: Support setting SSBOs on the context and turning them into descriptors
Reviewed-by: Sil Vilerino <sivileri@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14294>
This commit is contained in:
parent
49cf325d82
commit
32375789e5
4 changed files with 114 additions and 3 deletions
|
|
@ -1460,9 +1460,62 @@ d3d12_set_stream_output_targets(struct pipe_context *pctx,
|
|||
ctx->state_dirty |= D3D12_DIRTY_STREAM_OUTPUT;
|
||||
}
|
||||
|
||||
static void
|
||||
d3d12_decrement_uav_bind_count(struct d3d12_context *ctx,
|
||||
enum pipe_shader_type shader,
|
||||
struct d3d12_resource *res) {
|
||||
assert(res->bind_counts[shader][D3D12_RESOURCE_BINDING_TYPE_UAV] > 0);
|
||||
res->bind_counts[shader][D3D12_RESOURCE_BINDING_TYPE_UAV]--;
|
||||
}
|
||||
|
||||
static void
|
||||
d3d12_increment_uav_bind_count(struct d3d12_context *ctx,
|
||||
enum pipe_shader_type shader,
|
||||
struct d3d12_resource *res) {
|
||||
res->bind_counts[shader][D3D12_RESOURCE_BINDING_TYPE_UAV]++;
|
||||
}
|
||||
|
||||
static void
|
||||
d3d12_set_shader_buffers(struct pipe_context *pctx,
|
||||
enum pipe_shader_type shader,
|
||||
unsigned start_slot, unsigned count,
|
||||
const struct pipe_shader_buffer *buffers,
|
||||
unsigned writable_bitmask)
|
||||
{
|
||||
struct d3d12_context *ctx = d3d12_context(pctx);
|
||||
for (unsigned i = 0; i < count; ++i) {
|
||||
struct pipe_shader_buffer *slot = &ctx->ssbo_views[shader][i + start_slot];
|
||||
if (slot->buffer) {
|
||||
d3d12_decrement_uav_bind_count(ctx, shader, d3d12_resource(slot->buffer));
|
||||
pipe_resource_reference(&slot->buffer, NULL);
|
||||
}
|
||||
|
||||
if (buffers && buffers[i].buffer) {
|
||||
pipe_resource_reference(&slot->buffer, buffers[i].buffer);
|
||||
slot->buffer_offset = buffers[i].buffer_offset;
|
||||
slot->buffer_size = buffers[i].buffer_size;
|
||||
d3d12_increment_uav_bind_count(ctx, shader, d3d12_resource(buffers[i].buffer));
|
||||
} else
|
||||
memset(slot, 0, sizeof(*slot));
|
||||
}
|
||||
|
||||
if (buffers) {
|
||||
ctx->num_ssbo_views[shader] = MAX2(ctx->num_ssbo_views[shader], count + start_slot);
|
||||
} else {
|
||||
ctx->num_ssbo_views[shader] = 0;
|
||||
for (int i = start_slot + count - 1; i >= (int)start_slot; --i) {
|
||||
if (ctx->ssbo_views[shader][i].buffer) {
|
||||
ctx->num_ssbo_views[shader] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx->shader_dirty[shader] |= D3D12_SHADER_DIRTY_UAVS;
|
||||
}
|
||||
|
||||
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
|
||||
// For each shader type, if the resource is currently bound as CBV, SRV, or UAV
|
||||
// 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) {
|
||||
|
|
@ -1472,6 +1525,10 @@ d3d12_invalidate_context_bindings(struct d3d12_context *ctx, struct d3d12_resour
|
|||
if (res->bind_counts[i][D3D12_RESOURCE_BINDING_TYPE_SRV] > 0) {
|
||||
ctx->shader_dirty[i] |= D3D12_SHADER_DIRTY_SAMPLER_VIEWS;
|
||||
}
|
||||
|
||||
if (res->bind_counts[i][D3D12_RESOURCE_BINDING_TYPE_UAV] > 0) {
|
||||
ctx->shader_dirty[i] |= D3D12_SHADER_DIRTY_UAVS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1966,6 +2023,8 @@ d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
|||
ctx->base.stream_output_target_destroy = d3d12_stream_output_target_destroy;
|
||||
ctx->base.set_stream_output_targets = d3d12_set_stream_output_targets;
|
||||
|
||||
ctx->base.set_shader_buffers = d3d12_set_shader_buffers;
|
||||
|
||||
ctx->base.get_timestamp = d3d12_get_timestamp;
|
||||
|
||||
ctx->base.clear = d3d12_clear;
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ enum d3d12_shader_dirty_flags
|
|||
D3D12_SHADER_DIRTY_CONSTBUF = (1 << 0),
|
||||
D3D12_SHADER_DIRTY_SAMPLER_VIEWS = (1 << 1),
|
||||
D3D12_SHADER_DIRTY_SAMPLERS = (1 << 2),
|
||||
D3D12_SHADER_DIRTY_UAVS = (1 << 3),
|
||||
};
|
||||
|
||||
#define D3D12_DIRTY_PSO (D3D12_DIRTY_BLEND | D3D12_DIRTY_RASTERIZER | D3D12_DIRTY_ZSA | \
|
||||
|
|
@ -78,7 +79,7 @@ enum d3d12_shader_dirty_flags
|
|||
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_SAMPLERS | D3D12_SHADER_DIRTY_UAVS)
|
||||
|
||||
enum d3d12_binding_type {
|
||||
D3D12_BINDING_CONSTANT_BUFFER,
|
||||
|
|
@ -181,6 +182,8 @@ struct d3d12_context {
|
|||
struct pipe_sampler_view *sampler_views[PIPE_SHADER_TYPES][PIPE_MAX_SHADER_SAMPLER_VIEWS];
|
||||
unsigned num_sampler_views[PIPE_SHADER_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 d3d12_sampler_state *samplers[PIPE_SHADER_TYPES][PIPE_MAX_SAMPLERS];
|
||||
unsigned num_samplers[PIPE_SHADER_TYPES];
|
||||
D3D12_INDEX_BUFFER_VIEW ibv;
|
||||
|
|
|
|||
|
|
@ -138,6 +138,45 @@ fill_srv_descriptors(struct d3d12_context *ctx,
|
|||
return table_start.gpu_handle;
|
||||
}
|
||||
|
||||
static D3D12_GPU_DESCRIPTOR_HANDLE
|
||||
fill_uav_descriptors(struct d3d12_context *ctx,
|
||||
const struct d3d12_shader *shader,
|
||||
int stage)
|
||||
{
|
||||
struct d3d12_batch *batch = d3d12_current_batch(ctx);
|
||||
struct d3d12_descriptor_handle table_start;
|
||||
|
||||
d2d12_descriptor_heap_get_next_handle(batch->view_heap, &table_start);
|
||||
|
||||
for (unsigned i = 0; i < shader->nir->info.num_ssbos; i++)
|
||||
{
|
||||
struct pipe_shader_buffer *view = &ctx->ssbo_views[stage][i];
|
||||
|
||||
D3D12_UNORDERED_ACCESS_VIEW_DESC uav_desc;
|
||||
uav_desc.ViewDimension = D3D12_UAV_DIMENSION_BUFFER;
|
||||
uav_desc.Format = DXGI_FORMAT_R32_TYPELESS;
|
||||
uav_desc.Buffer.Flags = D3D12_BUFFER_UAV_FLAG_RAW;
|
||||
uav_desc.Buffer.StructureByteStride = 0;
|
||||
uav_desc.Buffer.CounterOffsetInBytes = 0;
|
||||
ID3D12Resource *d3d12_res = nullptr;
|
||||
if (view->buffer) {
|
||||
struct d3d12_resource *res = d3d12_resource(view->buffer);
|
||||
uint64_t res_offset = 0;
|
||||
d3d12_res = d3d12_resource_underlying(res, &res_offset);
|
||||
d3d12_transition_resource_state(ctx, res, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_BIND_INVALIDATE_NONE);
|
||||
uav_desc.Buffer.FirstElement = (view->buffer_offset + res_offset) / 4;
|
||||
uav_desc.Buffer.NumElements = DIV_ROUND_UP(view->buffer_size, 4);
|
||||
d3d12_batch_reference_resource(batch, res, true);
|
||||
}
|
||||
|
||||
struct d3d12_descriptor_handle handle;
|
||||
d3d12_descriptor_heap_alloc_handle(batch->view_heap, &handle);
|
||||
d3d12_screen(ctx->base.screen)->dev->CreateUnorderedAccessView(d3d12_res, nullptr, &uav_desc, handle.cpu_handle);
|
||||
}
|
||||
|
||||
return table_start.gpu_handle;
|
||||
}
|
||||
|
||||
static D3D12_GPU_DESCRIPTOR_HANDLE
|
||||
fill_sampler_descriptors(struct d3d12_context *ctx,
|
||||
const struct d3d12_shader_selector *shader_sel,
|
||||
|
|
@ -229,6 +268,7 @@ check_descriptors_left(struct d3d12_context *ctx)
|
|||
|
||||
needed_descs += shader->current->num_cb_bindings;
|
||||
needed_descs += shader->current->end_srv_binding - shader->current->begin_srv_binding;
|
||||
needed_descs += shader->current->nir->info.num_ssbos;
|
||||
}
|
||||
|
||||
if (d3d12_descriptor_heap_get_remaining_handles(batch->view_heap) < needed_descs)
|
||||
|
|
@ -250,7 +290,7 @@ check_descriptors_left(struct d3d12_context *ctx)
|
|||
return true;
|
||||
}
|
||||
|
||||
#define MAX_DESCRIPTOR_TABLES (D3D12_GFX_SHADER_STAGES * 3)
|
||||
#define MAX_DESCRIPTOR_TABLES (D3D12_GFX_SHADER_STAGES * 4)
|
||||
|
||||
static unsigned
|
||||
update_graphics_root_parameters(struct d3d12_context *ctx,
|
||||
|
|
@ -300,6 +340,14 @@ update_graphics_root_parameters(struct d3d12_context *ctx,
|
|||
ctx->cmdlist->SetGraphicsRoot32BitConstants(num_params, size, constants, 0);
|
||||
num_params++;
|
||||
}
|
||||
if (shader->nir->info.num_ssbos > 0) {
|
||||
if (dirty & D3D12_SHADER_DIRTY_UAVS) {
|
||||
assert(num_root_desciptors < MAX_DESCRIPTOR_TABLES);
|
||||
root_desc_tables[num_root_desciptors] = fill_uav_descriptors(ctx, shader, i);
|
||||
root_desc_indices[num_root_desciptors++] = num_params;
|
||||
}
|
||||
num_params++;
|
||||
}
|
||||
}
|
||||
return num_root_desciptors;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ struct pipe_screen;
|
|||
enum d3d12_resource_binding_type {
|
||||
D3D12_RESOURCE_BINDING_TYPE_SRV,
|
||||
D3D12_RESOURCE_BINDING_TYPE_CBV,
|
||||
D3D12_RESOURCE_BINDING_TYPE_UAV,
|
||||
D3D12_RESOURCE_BINDING_TYPES
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue