d3d12: Move indirect compute to real indirect dispatches
Reviewed-by: Sil Vilerino <sivileri@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14787>
This commit is contained in:
@@ -41,11 +41,11 @@ create_cmd_signature(struct d3d12_context *ctx, const struct d3d12_cmd_signature
|
||||
D3D12_INDIRECT_ARGUMENT_DESC indirect_args[2] = {};
|
||||
|
||||
unsigned num_args = 0;
|
||||
if (key->draw_params) {
|
||||
if (key->draw_or_dispatch_params) {
|
||||
indirect_args[num_args].Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT;
|
||||
indirect_args[num_args].Constant.RootParameterIndex = key->draw_params_root_const_param;
|
||||
indirect_args[num_args].Constant.DestOffsetIn32BitValues = key->draw_params_root_const_offset;
|
||||
indirect_args[num_args++].Constant.Num32BitValuesToSet = 4;
|
||||
indirect_args[num_args].Constant.RootParameterIndex = key->params_root_const_param;
|
||||
indirect_args[num_args].Constant.DestOffsetIn32BitValues = key->params_root_const_offset;
|
||||
indirect_args[num_args++].Constant.Num32BitValuesToSet = key->compute ? 3 : 4;
|
||||
}
|
||||
|
||||
indirect_args[num_args++].Type = key->compute ? D3D12_INDIRECT_ARGUMENT_TYPE_DISPATCH :
|
||||
@@ -62,7 +62,7 @@ create_cmd_signature(struct d3d12_context *ctx, const struct d3d12_cmd_signature
|
||||
}
|
||||
|
||||
ID3D12CommandSignature *
|
||||
d3d12_get_gfx_cmd_signature(struct d3d12_context *ctx,
|
||||
d3d12_get_cmd_signature(struct d3d12_context *ctx,
|
||||
const struct d3d12_cmd_signature_key *key)
|
||||
{
|
||||
struct hash_entry *entry = _mesa_hash_table_search(ctx->cmd_signature_cache, &key);
|
||||
|
||||
@@ -29,10 +29,10 @@
|
||||
struct d3d12_cmd_signature_key {
|
||||
uint8_t compute:1;
|
||||
uint8_t indexed:1;
|
||||
uint8_t draw_params:1;
|
||||
uint8_t draw_or_dispatch_params:1;
|
||||
/* 5 bits padding */
|
||||
uint8_t draw_params_root_const_param;
|
||||
uint8_t draw_params_root_const_offset;
|
||||
uint8_t params_root_const_param;
|
||||
uint8_t params_root_const_offset;
|
||||
/* 8 bits padding */
|
||||
|
||||
unsigned multi_draw_stride;
|
||||
@@ -48,7 +48,7 @@ void
|
||||
d3d12_cmd_signature_cache_destroy(struct d3d12_context *ctx);
|
||||
|
||||
ID3D12CommandSignature *
|
||||
d3d12_get_gfx_cmd_signature(struct d3d12_context *ctx,
|
||||
const struct d3d12_cmd_signature_key *key);
|
||||
d3d12_get_cmd_signature(struct d3d12_context *ctx,
|
||||
const struct d3d12_cmd_signature_key *key);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -370,9 +370,9 @@ fill_graphics_state_vars(struct d3d12_context *ctx,
|
||||
ptr[1] = dinfo->start_instance;
|
||||
ptr[2] = drawid;
|
||||
ptr[3] = dinfo->index_size ? -1 : 0;
|
||||
cmd_sig_key->draw_params = 1;
|
||||
cmd_sig_key->draw_or_dispatch_params = 1;
|
||||
cmd_sig_key->root_sig = ctx->gfx_pipeline_state.root_signature;
|
||||
cmd_sig_key->draw_params_root_const_offset = size;
|
||||
cmd_sig_key->params_root_const_offset = size;
|
||||
size += 4;
|
||||
break;
|
||||
case D3D12_STATE_VAR_DEPTH_TRANSFORM:
|
||||
@@ -404,7 +404,8 @@ static unsigned
|
||||
fill_compute_state_vars(struct d3d12_context *ctx,
|
||||
const struct pipe_grid_info *info,
|
||||
struct d3d12_shader *shader,
|
||||
uint32_t *values)
|
||||
uint32_t *values,
|
||||
struct d3d12_cmd_signature_key *cmd_sig_key)
|
||||
{
|
||||
unsigned size = 0;
|
||||
|
||||
@@ -416,6 +417,9 @@ fill_compute_state_vars(struct d3d12_context *ctx,
|
||||
ptr[0] = info->grid[0];
|
||||
ptr[1] = info->grid[1];
|
||||
ptr[2] = info->grid[2];
|
||||
cmd_sig_key->draw_or_dispatch_params = 1;
|
||||
cmd_sig_key->root_sig = ctx->compute_pipeline_state.root_signature;
|
||||
cmd_sig_key->params_root_const_offset = size;
|
||||
size += 4;
|
||||
break;
|
||||
case D3D12_STATE_VAR_TRANSFORM_GENERIC0: {
|
||||
@@ -550,8 +554,8 @@ update_graphics_root_parameters(struct d3d12_context *ctx,
|
||||
if (shader_sel->current->num_state_vars > 0) {
|
||||
uint32_t constants[D3D12_MAX_GRAPHICS_STATE_VARS * 4];
|
||||
unsigned size = fill_graphics_state_vars(ctx, dinfo, drawid, draw, shader_sel->current, constants, cmd_sig_key);
|
||||
if (cmd_sig_key->draw_params)
|
||||
cmd_sig_key->draw_params_root_const_param = num_params;
|
||||
if (cmd_sig_key->draw_or_dispatch_params)
|
||||
cmd_sig_key->params_root_const_param = num_params;
|
||||
ctx->cmdlist->SetGraphicsRoot32BitConstants(num_params, size, constants, 0);
|
||||
num_params++;
|
||||
}
|
||||
@@ -563,7 +567,8 @@ static unsigned
|
||||
update_compute_root_parameters(struct d3d12_context *ctx,
|
||||
const struct pipe_grid_info *info,
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE root_desc_tables[MAX_DESCRIPTOR_TABLES],
|
||||
int root_desc_indices[MAX_DESCRIPTOR_TABLES])
|
||||
int root_desc_indices[MAX_DESCRIPTOR_TABLES],
|
||||
struct d3d12_cmd_signature_key *cmd_sig_key)
|
||||
{
|
||||
unsigned num_params = 0;
|
||||
unsigned num_root_descriptors = 0;
|
||||
@@ -574,7 +579,9 @@ update_compute_root_parameters(struct d3d12_context *ctx,
|
||||
/* TODO Don't always update state vars */
|
||||
if (shader_sel->current->num_state_vars > 0) {
|
||||
uint32_t constants[D3D12_MAX_COMPUTE_STATE_VARS * 4];
|
||||
unsigned size = fill_compute_state_vars(ctx, info, shader_sel->current, constants);
|
||||
unsigned size = fill_compute_state_vars(ctx, info, shader_sel->current, constants, cmd_sig_key);
|
||||
if (cmd_sig_key->draw_or_dispatch_params)
|
||||
cmd_sig_key->params_root_const_param = num_params;
|
||||
ctx->cmdlist->SetComputeRoot32BitConstants(num_params, size, constants, 0);
|
||||
num_params++;
|
||||
}
|
||||
@@ -1180,7 +1187,7 @@ d3d12_draw_vbo(struct pipe_context *pctx,
|
||||
ctx->cmdlist->SetGraphicsRootDescriptorTable(root_desc_indices[i], root_desc_tables[i]);
|
||||
|
||||
if (indirect) {
|
||||
ID3D12CommandSignature *cmd_sig = d3d12_get_gfx_cmd_signature(ctx, &cmd_sig_key);
|
||||
ID3D12CommandSignature *cmd_sig = d3d12_get_cmd_signature(ctx, &cmd_sig_key);
|
||||
ctx->cmdlist->ExecuteIndirect(cmd_sig, indirect->draw_count, indirect_arg_buf,
|
||||
indirect_arg_offset, indirect_count_buf, indirect_count_offset);
|
||||
} else {
|
||||
@@ -1215,25 +1222,61 @@ d3d12_draw_vbo(struct pipe_context *pctx,
|
||||
pipe_resource_reference(&patched_indirect.buffer, NULL);
|
||||
}
|
||||
|
||||
static bool
|
||||
update_dispatch_indirect_with_sysvals(struct d3d12_context *ctx,
|
||||
struct pipe_resource **indirect_inout,
|
||||
unsigned *indirect_offset_inout,
|
||||
struct pipe_resource **indirect_out)
|
||||
{
|
||||
if (*indirect_inout == nullptr ||
|
||||
ctx->compute_state == nullptr)
|
||||
return false;
|
||||
|
||||
if (!BITSET_TEST(ctx->compute_state->current->nir->info.system_values_read, SYSTEM_VALUE_NUM_WORKGROUPS))
|
||||
return false;
|
||||
|
||||
if (ctx->current_predication)
|
||||
ctx->cmdlist->SetPredication(nullptr, 0, D3D12_PREDICATION_OP_EQUAL_ZERO);
|
||||
|
||||
auto indirect_in = *indirect_inout;
|
||||
|
||||
/* 6 uints: 2 copies of the indirect arg buffer */
|
||||
pipe_resource output_buf_templ = {};
|
||||
output_buf_templ.target = PIPE_BUFFER;
|
||||
output_buf_templ.width0 = sizeof(uint32_t) * 6;
|
||||
output_buf_templ.height0 = output_buf_templ.depth0 = output_buf_templ.array_size =
|
||||
output_buf_templ.last_level = 1;
|
||||
output_buf_templ.usage = PIPE_USAGE_DEFAULT;
|
||||
*indirect_out = ctx->base.screen->resource_create(ctx->base.screen, &output_buf_templ);
|
||||
|
||||
struct pipe_box src_box = { (int)*indirect_offset_inout, 0, 0, sizeof(uint32_t) * 3, 1, 1 };
|
||||
ctx->base.resource_copy_region(&ctx->base, *indirect_out, 0, 0, 0, 0, indirect_in, 0, &src_box);
|
||||
ctx->base.resource_copy_region(&ctx->base, *indirect_out, 0, src_box.width, 0, 0, indirect_in, 0, &src_box);
|
||||
|
||||
if (ctx->current_predication)
|
||||
d3d12_enable_predication(ctx);
|
||||
|
||||
*indirect_inout = *indirect_out;
|
||||
*indirect_offset_inout = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
d3d12_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info)
|
||||
{
|
||||
struct d3d12_context *ctx = d3d12_context(pctx);
|
||||
struct d3d12_batch *batch;
|
||||
struct pipe_resource *patched_indirect = nullptr;
|
||||
|
||||
if (info->indirect) {
|
||||
/* TODO: Use a compute shader to retrieve state vars if necessary, and do an actual indirect dispatch */
|
||||
pipe_box box = { (int)info->indirect_offset, 0, 0, sizeof(info->grid), 1, 1 };
|
||||
pipe_transfer *transfer = nullptr;
|
||||
void *map = pctx->buffer_map(pctx, info->indirect, 0, PIPE_MAP_READ, &box, &transfer);
|
||||
pipe_grid_info new_info = *info;
|
||||
new_info.indirect = nullptr;
|
||||
memcpy(new_info.grid, map, sizeof(new_info.grid));
|
||||
pctx->buffer_unmap(pctx, transfer);
|
||||
struct d3d12_cmd_signature_key cmd_sig_key;
|
||||
memset(&cmd_sig_key, 0, sizeof(cmd_sig_key));
|
||||
cmd_sig_key.compute = 1;
|
||||
cmd_sig_key.multi_draw_stride = sizeof(D3D12_DISPATCH_ARGUMENTS);
|
||||
|
||||
d3d12_launch_grid(pctx, &new_info);
|
||||
return;
|
||||
}
|
||||
struct pipe_resource *indirect = info->indirect;
|
||||
unsigned indirect_offset = info->indirect_offset;
|
||||
if (indirect && update_dispatch_indirect_with_sysvals(ctx, &indirect, &indirect_offset, &patched_indirect))
|
||||
cmd_sig_key.multi_draw_stride = sizeof(D3D12_DISPATCH_ARGUMENTS) * 2;
|
||||
|
||||
d3d12_select_compute_shader_variants(ctx, info);
|
||||
d3d12_validate_queries(ctx);
|
||||
@@ -1276,14 +1319,31 @@ d3d12_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info)
|
||||
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE root_desc_tables[MAX_DESCRIPTOR_TABLES];
|
||||
int root_desc_indices[MAX_DESCRIPTOR_TABLES];
|
||||
unsigned num_root_descriptors = update_compute_root_parameters(ctx, info, root_desc_tables, root_desc_indices);
|
||||
unsigned num_root_descriptors = update_compute_root_parameters(ctx, info, root_desc_tables, root_desc_indices, &cmd_sig_key);
|
||||
|
||||
ID3D12Resource *indirect_arg_buf = nullptr;
|
||||
uint64_t indirect_arg_offset = 0;
|
||||
if (indirect) {
|
||||
struct d3d12_resource *indirect_buf = d3d12_resource(indirect);
|
||||
uint64_t buf_offset = 0;
|
||||
indirect_arg_buf = d3d12_resource_underlying(indirect_buf, &buf_offset);
|
||||
indirect_arg_offset = indirect_offset + buf_offset;
|
||||
d3d12_transition_resource_state(ctx, indirect_buf,
|
||||
D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT, D3D12_BIND_INVALIDATE_NONE);
|
||||
d3d12_batch_reference_resource(batch, indirect_buf, false);
|
||||
}
|
||||
|
||||
d3d12_apply_resource_states(ctx, ctx->compute_state->is_variant);
|
||||
|
||||
for (unsigned i = 0; i < num_root_descriptors; ++i)
|
||||
ctx->cmdlist->SetComputeRootDescriptorTable(root_desc_indices[i], root_desc_tables[i]);
|
||||
|
||||
ctx->cmdlist->Dispatch(info->grid[0], info->grid[1], info->grid[2]);
|
||||
if (indirect) {
|
||||
ID3D12CommandSignature *cmd_sig = d3d12_get_cmd_signature(ctx, &cmd_sig_key);
|
||||
ctx->cmdlist->ExecuteIndirect(cmd_sig, 1, indirect_arg_buf, indirect_arg_offset, nullptr, 0);
|
||||
} else {
|
||||
ctx->cmdlist->Dispatch(info->grid[0], info->grid[1], info->grid[2]);
|
||||
}
|
||||
|
||||
ctx->state_dirty &= D3D12_DIRTY_GFX_MASK;
|
||||
ctx->cmdlist_dirty &= D3D12_DIRTY_GFX_MASK;
|
||||
@@ -1293,4 +1353,5 @@ d3d12_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info)
|
||||
batch->pending_memory_barrier = false;
|
||||
|
||||
ctx->shader_dirty[PIPE_SHADER_COMPUTE] = 0;
|
||||
pipe_resource_reference(&patched_indirect, nullptr);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user