mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 05:18:08 +02:00
dzn: Rework indirect drawing keys for shaders and command signatures
When we don't need emulation of first vertex, base instance, draw ID sysvals, or triangle fans, we can have very simple command signatures and indirect arg buffer generation shaders. The next step is to handle the case where everything can be supported straight from the app's buffer. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28383>
This commit is contained in:
parent
ccf439629f
commit
d7bd87aa27
6 changed files with 189 additions and 216 deletions
|
|
@ -3785,6 +3785,7 @@ dzn_cmd_buffer_indirect_draw(struct dzn_cmd_buffer *cmdbuf,
|
|||
bool indexed)
|
||||
{
|
||||
struct dzn_device *device = container_of(cmdbuf->vk.base.device, struct dzn_device, vk);
|
||||
struct dzn_physical_device *pdev = container_of(device->vk.physical, struct dzn_physical_device, vk);
|
||||
struct dzn_graphics_pipeline *pipeline = (struct dzn_graphics_pipeline *)
|
||||
cmdbuf->state.bindpoint[VK_PIPELINE_BIND_POINT_GRAPHICS].pipeline;
|
||||
uint32_t min_draw_buf_stride =
|
||||
|
|
@ -3801,10 +3802,21 @@ dzn_cmd_buffer_indirect_draw(struct dzn_cmd_buffer *cmdbuf,
|
|||
uint32_t triangle_fan_index_buf_stride =
|
||||
dzn_cmd_buffer_triangle_fan_get_max_index_buf_size(cmdbuf, indexed) *
|
||||
sizeof(uint32_t);
|
||||
|
||||
struct dzn_indirect_draw_type draw_type;
|
||||
draw_type.value = 0;
|
||||
draw_type.indexed = indexed;
|
||||
draw_type.indirect_count = count_buf != NULL;
|
||||
draw_type.draw_params = pipeline->needs_draw_sysvals && !pdev->options21.ExtendedCommandInfoSupported;
|
||||
draw_type.draw_id = max_draw_count > 1 && pdev->options21.ExecuteIndirectTier < D3D12_EXECUTE_INDIRECT_TIER_1_1;
|
||||
draw_type.triangle_fan = triangle_fan_index_buf_stride > 0;
|
||||
draw_type.triangle_fan_primitive_restart = draw_type.triangle_fan && prim_restart;
|
||||
|
||||
uint32_t exec_buf_stride =
|
||||
triangle_fan_index_buf_stride > 0 ?
|
||||
sizeof(struct dzn_indirect_triangle_fan_draw_exec_params) :
|
||||
sizeof(struct dzn_indirect_draw_exec_params);
|
||||
(draw_type.triangle_fan ? sizeof(D3D12_INDEX_BUFFER_VIEW) : 0) +
|
||||
(draw_type.draw_params ? sizeof(uint32_t) * 2 : 0) +
|
||||
(draw_type.draw_id ? sizeof(uint32_t) : 0) +
|
||||
min_draw_buf_stride;
|
||||
uint32_t triangle_fan_exec_buf_stride =
|
||||
sizeof(struct dzn_indirect_triangle_fan_rewrite_index_exec_params);
|
||||
uint32_t exec_buf_size = max_draw_count * exec_buf_stride;
|
||||
|
|
@ -3872,30 +3884,7 @@ dzn_cmd_buffer_indirect_draw(struct dzn_cmd_buffer *cmdbuf,
|
|||
else
|
||||
params_size = sizeof(struct dzn_indirect_draw_rewrite_params);
|
||||
|
||||
enum dzn_indirect_draw_type draw_type;
|
||||
|
||||
if (indexed && triangle_fan_index_buf_stride > 0) {
|
||||
if (prim_restart && count_buf)
|
||||
draw_type = DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN_PRIM_RESTART;
|
||||
else if (prim_restart && !count_buf)
|
||||
draw_type = DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN_PRIM_RESTART;
|
||||
else if (!prim_restart && count_buf)
|
||||
draw_type = DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN;
|
||||
else
|
||||
draw_type = DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN;
|
||||
} else if (!indexed && triangle_fan_index_buf_stride > 0) {
|
||||
draw_type = count_buf ?
|
||||
DZN_INDIRECT_DRAW_COUNT_TRIANGLE_FAN :
|
||||
DZN_INDIRECT_DRAW_TRIANGLE_FAN;
|
||||
} else if (indexed) {
|
||||
draw_type = count_buf ?
|
||||
DZN_INDIRECT_INDEXED_DRAW_COUNT :
|
||||
DZN_INDIRECT_INDEXED_DRAW;
|
||||
} else {
|
||||
draw_type = count_buf ? DZN_INDIRECT_DRAW_COUNT : DZN_INDIRECT_DRAW;
|
||||
}
|
||||
|
||||
struct dzn_meta_indirect_draw *indirect_draw = &device->indirect_draws[draw_type];
|
||||
struct dzn_meta_indirect_draw *indirect_draw = &device->indirect_draws[draw_type.value];
|
||||
uint32_t root_param_idx = 0;
|
||||
|
||||
cmdbuf->state.bindpoint[VK_PIPELINE_BIND_POINT_COMPUTE].dirty |= DZN_CMD_BINDPOINT_DIRTY_PIPELINE;
|
||||
|
|
@ -4029,14 +4018,14 @@ dzn_cmd_buffer_indirect_draw(struct dzn_cmd_buffer *cmdbuf,
|
|||
DZN_CMD_BINDPOINT_DIRTY_PIPELINE;
|
||||
}
|
||||
|
||||
enum dzn_indirect_draw_cmd_sig_type cmd_sig_type =
|
||||
triangle_fan_index_buf_stride > 0 ?
|
||||
DZN_INDIRECT_DRAW_TRIANGLE_FAN_CMD_SIG :
|
||||
indexed ?
|
||||
DZN_INDIRECT_INDEXED_DRAW_CMD_SIG :
|
||||
DZN_INDIRECT_DRAW_CMD_SIG;
|
||||
struct dzn_indirect_draw_cmd_sig_key cmd_sig_key;
|
||||
cmd_sig_key.value = 0;
|
||||
cmd_sig_key.indexed = indexed;
|
||||
cmd_sig_key.triangle_fan = draw_type.triangle_fan;
|
||||
cmd_sig_key.draw_params = draw_type.draw_params;
|
||||
cmd_sig_key.draw_id = max_draw_count > 1;
|
||||
ID3D12CommandSignature *cmdsig =
|
||||
dzn_graphics_pipeline_get_indirect_cmd_sig(pipeline, cmd_sig_type);
|
||||
dzn_graphics_pipeline_get_indirect_cmd_sig(pipeline, cmd_sig_key);
|
||||
|
||||
if (!cmdsig) {
|
||||
vk_command_buffer_set_error(&cmdbuf->vk, VK_ERROR_OUT_OF_DEVICE_MEMORY);
|
||||
|
|
|
|||
|
|
@ -100,9 +100,9 @@ dzn_meta_compile_shader(struct dzn_device *device, nir_shader *nir,
|
|||
#define DZN_META_INDIRECT_DRAW_MAX_PARAM_COUNT 5
|
||||
|
||||
static void
|
||||
dzn_meta_indirect_draw_finish(struct dzn_device *device, enum dzn_indirect_draw_type type)
|
||||
dzn_meta_indirect_draw_finish(struct dzn_device *device, struct dzn_indirect_draw_type type)
|
||||
{
|
||||
struct dzn_meta_indirect_draw *meta = &device->indirect_draws[type];
|
||||
struct dzn_meta_indirect_draw *meta = &device->indirect_draws[type.value];
|
||||
|
||||
if (meta->root_sig)
|
||||
ID3D12RootSignature_Release(meta->root_sig);
|
||||
|
|
@ -113,9 +113,9 @@ dzn_meta_indirect_draw_finish(struct dzn_device *device, enum dzn_indirect_draw_
|
|||
|
||||
static VkResult
|
||||
dzn_meta_indirect_draw_init(struct dzn_device *device,
|
||||
enum dzn_indirect_draw_type type)
|
||||
struct dzn_indirect_draw_type type)
|
||||
{
|
||||
struct dzn_meta_indirect_draw *meta = &device->indirect_draws[type];
|
||||
struct dzn_meta_indirect_draw *meta = &device->indirect_draws[type.value];
|
||||
struct dzn_instance *instance =
|
||||
container_of(device->vk.physical->instance, struct dzn_instance, vk);
|
||||
VkResult ret = VK_SUCCESS;
|
||||
|
|
@ -123,23 +123,10 @@ dzn_meta_indirect_draw_init(struct dzn_device *device,
|
|||
glsl_type_singleton_init_or_ref();
|
||||
|
||||
nir_shader *nir = dzn_nir_indirect_draw_shader(type);
|
||||
bool triangle_fan = type == DZN_INDIRECT_DRAW_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_DRAW_COUNT_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN_PRIM_RESTART ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN_PRIM_RESTART;
|
||||
bool indirect_count = type == DZN_INDIRECT_DRAW_COUNT ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_COUNT ||
|
||||
type == DZN_INDIRECT_DRAW_COUNT_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN_PRIM_RESTART;
|
||||
bool prim_restart = type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN_PRIM_RESTART ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN_PRIM_RESTART;
|
||||
uint32_t shader_params_size =
|
||||
triangle_fan && prim_restart ?
|
||||
type.triangle_fan_primitive_restart ?
|
||||
sizeof(struct dzn_indirect_draw_triangle_fan_prim_restart_rewrite_params) :
|
||||
triangle_fan ?
|
||||
type.triangle_fan ?
|
||||
sizeof(struct dzn_indirect_draw_triangle_fan_rewrite_params) :
|
||||
sizeof(struct dzn_indirect_draw_rewrite_params);
|
||||
|
||||
|
|
@ -176,7 +163,7 @@ dzn_meta_indirect_draw_init(struct dzn_device *device,
|
|||
.ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL,
|
||||
};
|
||||
|
||||
if (indirect_count) {
|
||||
if (type.indirect_count) {
|
||||
root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV,
|
||||
.Descriptor = {
|
||||
|
|
@ -189,7 +176,7 @@ dzn_meta_indirect_draw_init(struct dzn_device *device,
|
|||
}
|
||||
|
||||
|
||||
if (triangle_fan) {
|
||||
if (type.triangle_fan) {
|
||||
root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) {
|
||||
.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV,
|
||||
.Descriptor = {
|
||||
|
|
@ -817,7 +804,7 @@ dzn_meta_finish(struct dzn_device *device)
|
|||
dzn_meta_triangle_fan_rewrite_index_finish(device, i);
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(device->indirect_draws); i++)
|
||||
dzn_meta_indirect_draw_finish(device, i);
|
||||
dzn_meta_indirect_draw_finish(device, (struct dzn_indirect_draw_type) { .value = i });
|
||||
|
||||
dzn_meta_blits_finish(device);
|
||||
}
|
||||
|
|
@ -825,22 +812,34 @@ dzn_meta_finish(struct dzn_device *device)
|
|||
VkResult
|
||||
dzn_meta_init(struct dzn_device *device)
|
||||
{
|
||||
struct dzn_physical_device *pdev = container_of(device->vk.physical, struct dzn_physical_device, vk);
|
||||
VkResult result = dzn_meta_blits_init(device);
|
||||
if (result != VK_SUCCESS)
|
||||
goto out;
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(device->indirect_draws); i++) {
|
||||
struct dzn_indirect_draw_type type = { .value = i };
|
||||
if (type.triangle_fan_primitive_restart && !type.triangle_fan)
|
||||
continue;
|
||||
if (type.triangle_fan && pdev->options15.TriangleFanSupported)
|
||||
continue;
|
||||
if (type.draw_params && pdev->options21.ExtendedCommandInfoSupported)
|
||||
continue;
|
||||
if (type.draw_id && pdev->options21.ExecuteIndirectTier >= D3D12_EXECUTE_INDIRECT_TIER_1_1)
|
||||
continue;
|
||||
VkResult result =
|
||||
dzn_meta_indirect_draw_init(device, i);
|
||||
dzn_meta_indirect_draw_init(device, type);
|
||||
if (result != VK_SUCCESS)
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(device->triangle_fan); i++) {
|
||||
VkResult result =
|
||||
dzn_meta_triangle_fan_rewrite_index_init(device, i);
|
||||
if (result != VK_SUCCESS)
|
||||
goto out;
|
||||
if (!pdev->options15.TriangleFanSupported) {
|
||||
for (uint32_t i = 0; i < ARRAY_SIZE(device->triangle_fan); i++) {
|
||||
VkResult result =
|
||||
dzn_meta_triangle_fan_rewrite_index_init(device, i);
|
||||
if (result != VK_SUCCESS)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
|
|||
|
|
@ -84,47 +84,16 @@ dzn_nir_create_bo_desc(nir_builder *b,
|
|||
}
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_indirect_draw_shader(enum dzn_indirect_draw_type type)
|
||||
dzn_nir_indirect_draw_shader(struct dzn_indirect_draw_type type)
|
||||
{
|
||||
const char *type_str[] = {
|
||||
"draw",
|
||||
"draw_count",
|
||||
"indexed_draw",
|
||||
"indexed_draw_count",
|
||||
"draw_triangle_fan",
|
||||
"draw_count_triangle_fan",
|
||||
"indexed_draw_triangle_fan",
|
||||
"indexed_draw_count_triangle_fan",
|
||||
"indexed_draw_triangle_fan_prim_restart",
|
||||
"indexed_draw_count_triangle_fan_prim_restart",
|
||||
};
|
||||
|
||||
assert(type < ARRAY_SIZE(type_str));
|
||||
|
||||
bool indexed = type == DZN_INDIRECT_INDEXED_DRAW ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_COUNT ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN_PRIM_RESTART ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN_PRIM_RESTART;
|
||||
bool triangle_fan = type == DZN_INDIRECT_DRAW_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_DRAW_COUNT_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN_PRIM_RESTART ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN_PRIM_RESTART;
|
||||
bool indirect_count = type == DZN_INDIRECT_DRAW_COUNT ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_COUNT ||
|
||||
type == DZN_INDIRECT_DRAW_COUNT_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN_PRIM_RESTART;
|
||||
bool prim_restart = type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN_PRIM_RESTART ||
|
||||
type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN_PRIM_RESTART;
|
||||
nir_builder b =
|
||||
nir_builder_init_simple_shader(MESA_SHADER_COMPUTE,
|
||||
dxil_get_base_nir_compiler_options(),
|
||||
"dzn_meta_indirect_%s()",
|
||||
type_str[type]);
|
||||
"dzn_meta_indirect_%sdraw%s%s%s()",
|
||||
type.indexed ? "indexed_" : "",
|
||||
type.indirect_count ? "_count" : "",
|
||||
type.triangle_fan ? "_triangle_fan" : "",
|
||||
type.triangle_fan_primitive_restart ? "_primitive_restart" : "");
|
||||
b.shader->info.internal = true;
|
||||
|
||||
nir_def *params_desc =
|
||||
|
|
@ -134,8 +103,8 @@ dzn_nir_indirect_draw_shader(enum dzn_indirect_draw_type type)
|
|||
nir_def *exec_buf_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 2, "exec_buf", ACCESS_NON_READABLE);
|
||||
|
||||
unsigned params_size;
|
||||
if (triangle_fan)
|
||||
unsigned params_size = 0;
|
||||
if (type.triangle_fan)
|
||||
params_size = sizeof(struct dzn_indirect_draw_triangle_fan_rewrite_params);
|
||||
else
|
||||
params_size = sizeof(struct dzn_indirect_draw_rewrite_params);
|
||||
|
|
@ -145,15 +114,24 @@ dzn_nir_indirect_draw_shader(enum dzn_indirect_draw_type type)
|
|||
params_desc, nir_imm_int(&b, 0),
|
||||
.align_mul = 4, .align_offset = 0, .range_base = 0, .range = ~0);
|
||||
|
||||
uint32_t exec_stride_imm = 0;
|
||||
uint32_t draw_args_offset = 0;
|
||||
if (type.triangle_fan)
|
||||
exec_stride_imm += sizeof(D3D12_INDEX_BUFFER_VIEW);
|
||||
if (type.draw_params)
|
||||
exec_stride_imm += sizeof(uint32_t) * 2;
|
||||
if (type.draw_id)
|
||||
exec_stride_imm += sizeof(uint32_t);
|
||||
draw_args_offset = exec_stride_imm;
|
||||
exec_stride_imm += (type.indexed || type.triangle_fan) ?
|
||||
sizeof(D3D12_DRAW_INDEXED_ARGUMENTS) : sizeof(D3D12_DRAW_ARGUMENTS);
|
||||
|
||||
nir_def *draw_stride = nir_channel(&b, params, 0);
|
||||
nir_def *exec_stride =
|
||||
triangle_fan ?
|
||||
nir_imm_int(&b, sizeof(struct dzn_indirect_triangle_fan_draw_exec_params)) :
|
||||
nir_imm_int(&b, sizeof(struct dzn_indirect_draw_exec_params));
|
||||
nir_def *exec_stride = nir_imm_int(&b, exec_stride_imm);
|
||||
nir_def *index =
|
||||
nir_channel(&b, nir_load_global_invocation_id(&b, 32), 0);
|
||||
|
||||
if (indirect_count) {
|
||||
if (type.indirect_count) {
|
||||
nir_def *count_buf_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 3, "count_buf", ACCESS_NON_WRITEABLE);
|
||||
|
||||
|
|
@ -173,37 +151,40 @@ dzn_nir_indirect_draw_shader(enum dzn_indirect_draw_type type)
|
|||
|
||||
/* The first entry contains the indirect count */
|
||||
nir_def *exec_offset =
|
||||
indirect_count ?
|
||||
type.indirect_count ?
|
||||
nir_imul(&b, exec_stride, nir_iadd_imm(&b, index, 1)) :
|
||||
nir_imul(&b, exec_stride, index);
|
||||
|
||||
nir_def *draw_info1 =
|
||||
nir_load_ssbo(&b, 4, 32, draw_buf_desc, draw_offset, .align_mul = 4);
|
||||
nir_def *draw_info2 =
|
||||
indexed ?
|
||||
type.indexed ?
|
||||
nir_load_ssbo(&b, 1, 32, draw_buf_desc,
|
||||
nir_iadd_imm(&b, draw_offset, 16), .align_mul = 4) :
|
||||
nir_imm_int(&b, 0);
|
||||
|
||||
nir_def *first_vertex = nir_channel(&b, draw_info1, indexed ? 3 : 2);
|
||||
nir_def *first_vertex = nir_channel(&b, draw_info1, type.indexed ? 3 : 2);
|
||||
nir_def *base_instance =
|
||||
indexed ? draw_info2 : nir_channel(&b, draw_info1, 3);
|
||||
type.indexed ? draw_info2 : nir_channel(&b, draw_info1, 3);
|
||||
|
||||
nir_def *exec_vals[8] = {
|
||||
first_vertex,
|
||||
base_instance,
|
||||
index,
|
||||
};
|
||||
uint32_t exec_val_idx = 0;
|
||||
nir_def *exec_vals[8] = { NULL };
|
||||
if (type.draw_params) {
|
||||
exec_vals[exec_val_idx++] = first_vertex;
|
||||
exec_vals[exec_val_idx++] = base_instance;
|
||||
}
|
||||
if (type.draw_id)
|
||||
exec_vals[exec_val_idx++] = index;
|
||||
|
||||
if (triangle_fan) {
|
||||
if (type.triangle_fan) {
|
||||
/* Patch {vertex,index}_count and first_index */
|
||||
nir_def *triangle_count =
|
||||
nir_usub_sat(&b, nir_channel(&b, draw_info1, 0), nir_imm_int(&b, 2));
|
||||
exec_vals[3] = nir_imul_imm(&b, triangle_count, 3);
|
||||
exec_vals[4] = nir_channel(&b, draw_info1, 1);
|
||||
exec_vals[5] = nir_imm_int(&b, 0);
|
||||
exec_vals[6] = first_vertex;
|
||||
exec_vals[7] = base_instance;
|
||||
exec_vals[exec_val_idx++] = nir_imul_imm(&b, triangle_count, 3);
|
||||
exec_vals[exec_val_idx++] = nir_channel(&b, draw_info1, 1);
|
||||
exec_vals[exec_val_idx++] = nir_imm_int(&b, 0);
|
||||
exec_vals[exec_val_idx++] = first_vertex;
|
||||
exec_vals[exec_val_idx++] = base_instance;
|
||||
|
||||
nir_def *triangle_fan_exec_buf_desc =
|
||||
dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 4,
|
||||
|
|
@ -225,11 +206,11 @@ dzn_nir_indirect_draw_shader(enum dzn_indirect_draw_type type)
|
|||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] = triangle_fan_index_buf_addr_lo;
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] = triangle_fan_index_buf_addr_hi;
|
||||
|
||||
if (prim_restart) {
|
||||
if (type.triangle_fan_primitive_restart) {
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] = nir_channel(&b, draw_info1, 2);
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] = nir_channel(&b, draw_info1, 0);
|
||||
uint32_t index_count_offset =
|
||||
offsetof(struct dzn_indirect_triangle_fan_draw_exec_params, indexed_draw.IndexCountPerInstance);
|
||||
uint32_t index_count_offset = draw_args_offset +
|
||||
offsetof(D3D12_DRAW_INDEXED_ARGUMENTS, IndexCountPerInstance);
|
||||
nir_def *exec_buf_start =
|
||||
nir_load_ubo(&b, 2, 32,
|
||||
params_desc, nir_imm_int(&b, 16),
|
||||
|
|
@ -247,7 +228,7 @@ dzn_nir_indirect_draw_shader(enum dzn_indirect_draw_type type)
|
|||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] = nir_imm_int(&b, 1);
|
||||
} else {
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] =
|
||||
indexed ? nir_channel(&b, draw_info1, 2) : nir_imm_int(&b, 0);
|
||||
type.indexed ? nir_channel(&b, draw_info1, 2) : nir_imm_int(&b, 0);
|
||||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] =
|
||||
triangle_count;
|
||||
}
|
||||
|
|
@ -255,7 +236,7 @@ dzn_nir_indirect_draw_shader(enum dzn_indirect_draw_type type)
|
|||
triangle_fan_exec_vals[triangle_fan_exec_param_count++] = nir_imm_int(&b, 1);
|
||||
|
||||
unsigned rewrite_index_exec_params =
|
||||
prim_restart ?
|
||||
type.triangle_fan_primitive_restart ?
|
||||
sizeof(struct dzn_indirect_triangle_fan_prim_restart_rewrite_index_exec_params) :
|
||||
sizeof(struct dzn_indirect_triangle_fan_rewrite_index_exec_params);
|
||||
nir_def *triangle_fan_exec_stride =
|
||||
|
|
@ -285,21 +266,24 @@ dzn_nir_indirect_draw_shader(enum dzn_indirect_draw_type type)
|
|||
.write_mask = 0xf, .access = ACCESS_NON_READABLE, .align_mul = 16);
|
||||
exec_offset = nir_iadd_imm(&b, exec_offset, ARRAY_SIZE(ibview_vals) * 4);
|
||||
} else {
|
||||
exec_vals[3] = nir_channel(&b, draw_info1, 0);
|
||||
exec_vals[4] = nir_channel(&b, draw_info1, 1);
|
||||
exec_vals[5] = nir_channel(&b, draw_info1, 2);
|
||||
exec_vals[6] = nir_channel(&b, draw_info1, 3);
|
||||
exec_vals[7] = draw_info2;
|
||||
exec_vals[exec_val_idx++] = nir_channel(&b, draw_info1, 0);
|
||||
exec_vals[exec_val_idx++] = nir_channel(&b, draw_info1, 1);
|
||||
exec_vals[exec_val_idx++] = nir_channel(&b, draw_info1, 2);
|
||||
exec_vals[exec_val_idx++] = nir_channel(&b, draw_info1, 3);
|
||||
if (type.indexed)
|
||||
exec_vals[exec_val_idx++] = draw_info2;
|
||||
}
|
||||
|
||||
nir_store_ssbo(&b, nir_vec(&b, exec_vals, 4),
|
||||
nir_store_ssbo(&b, nir_vec(&b, exec_vals, MIN2(exec_val_idx, 4)),
|
||||
exec_buf_desc, exec_offset,
|
||||
.write_mask = 0xf, .access = ACCESS_NON_READABLE, .align_mul = 16);
|
||||
nir_store_ssbo(&b, nir_vec(&b, &exec_vals[4], 4),
|
||||
exec_buf_desc, nir_iadd_imm(&b, exec_offset, 16),
|
||||
.write_mask = 0xf, .access = ACCESS_NON_READABLE, .align_mul = 16);
|
||||
.write_mask = ((1 << exec_val_idx) - 1) & 0xf, .access = ACCESS_NON_READABLE, .align_mul = 16);
|
||||
if (exec_val_idx > 4) {
|
||||
nir_store_ssbo(&b, nir_vec(&b, &exec_vals[4], exec_val_idx - 4),
|
||||
exec_buf_desc, nir_iadd_imm(&b, exec_offset, 16),
|
||||
.write_mask = ((1 << (exec_val_idx - 4)) - 1) & 0xf, .access = ACCESS_NON_READABLE, .align_mul = 16);
|
||||
}
|
||||
|
||||
if (indirect_count)
|
||||
if (type.indirect_count)
|
||||
nir_pop_if(&b, NULL);
|
||||
|
||||
return b.shader;
|
||||
|
|
|
|||
|
|
@ -48,31 +48,6 @@ struct dzn_indirect_draw_triangle_fan_prim_restart_rewrite_params {
|
|||
uint64_t exec_buf_start;
|
||||
};
|
||||
|
||||
struct dzn_indirect_draw_exec_params {
|
||||
struct {
|
||||
uint32_t first_vertex;
|
||||
uint32_t base_instance;
|
||||
uint32_t draw_id;
|
||||
} sysvals;
|
||||
union {
|
||||
D3D12_DRAW_ARGUMENTS draw;
|
||||
D3D12_DRAW_INDEXED_ARGUMENTS indexed_draw;
|
||||
};
|
||||
};
|
||||
|
||||
struct dzn_indirect_triangle_fan_draw_exec_params {
|
||||
D3D12_INDEX_BUFFER_VIEW ibview;
|
||||
struct {
|
||||
uint32_t first_vertex;
|
||||
uint32_t base_instance;
|
||||
uint32_t draw_id;
|
||||
} sysvals;
|
||||
union {
|
||||
D3D12_DRAW_ARGUMENTS draw;
|
||||
D3D12_DRAW_INDEXED_ARGUMENTS indexed_draw;
|
||||
};
|
||||
};
|
||||
|
||||
struct dzn_triangle_fan_rewrite_index_params {
|
||||
uint32_t first_index;
|
||||
};
|
||||
|
|
@ -99,22 +74,23 @@ struct dzn_indirect_triangle_fan_prim_restart_rewrite_index_exec_params {
|
|||
} group_count;
|
||||
};
|
||||
|
||||
enum dzn_indirect_draw_type {
|
||||
DZN_INDIRECT_DRAW,
|
||||
DZN_INDIRECT_DRAW_COUNT,
|
||||
DZN_INDIRECT_INDEXED_DRAW,
|
||||
DZN_INDIRECT_INDEXED_DRAW_COUNT,
|
||||
DZN_INDIRECT_DRAW_TRIANGLE_FAN,
|
||||
DZN_INDIRECT_DRAW_COUNT_TRIANGLE_FAN,
|
||||
DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN,
|
||||
DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN,
|
||||
DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN_PRIM_RESTART,
|
||||
DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN_PRIM_RESTART,
|
||||
DZN_NUM_INDIRECT_DRAW_TYPES,
|
||||
struct dzn_indirect_draw_type {
|
||||
union {
|
||||
struct {
|
||||
uint8_t indexed : 1;
|
||||
uint8_t indirect_count : 1;
|
||||
uint8_t draw_params : 1;
|
||||
uint8_t draw_id : 1;
|
||||
uint8_t triangle_fan : 1;
|
||||
uint8_t triangle_fan_primitive_restart : 1;
|
||||
};
|
||||
uint8_t value;
|
||||
};
|
||||
};
|
||||
#define DZN_NUM_INDIRECT_DRAW_TYPES (1 << 6)
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_indirect_draw_shader(enum dzn_indirect_draw_type type);
|
||||
dzn_nir_indirect_draw_shader(struct dzn_indirect_draw_type type);
|
||||
|
||||
nir_shader *
|
||||
dzn_nir_triangle_fan_rewrite_index_shader(uint8_t old_index_size);
|
||||
|
|
|
|||
|
|
@ -245,7 +245,8 @@ dzn_pipeline_get_nir_shader(struct dzn_device *device,
|
|||
.register_space = DZN_REGISTER_SPACE_PUSH_CONSTANT,
|
||||
.base_shader_register = 0,
|
||||
},
|
||||
.first_vertex_and_base_instance_mode = DXIL_SPIRV_SYSVAL_TYPE_RUNTIME_DATA,
|
||||
.first_vertex_and_base_instance_mode = pdev->options21.ExtendedCommandInfoSupported ?
|
||||
DXIL_SPIRV_SYSVAL_TYPE_NATIVE : DXIL_SPIRV_SYSVAL_TYPE_RUNTIME_DATA,
|
||||
.workgroup_id_mode = DXIL_SPIRV_SYSVAL_TYPE_RUNTIME_DATA,
|
||||
.yz_flip = {
|
||||
.mode = options->yz_flip_mode,
|
||||
|
|
@ -2247,73 +2248,91 @@ dzn_graphics_pipeline_get_state(struct dzn_graphics_pipeline *pipeline,
|
|||
|
||||
ID3D12CommandSignature *
|
||||
dzn_graphics_pipeline_get_indirect_cmd_sig(struct dzn_graphics_pipeline *pipeline,
|
||||
enum dzn_indirect_draw_cmd_sig_type type)
|
||||
struct dzn_indirect_draw_cmd_sig_key key)
|
||||
{
|
||||
assert(type < DZN_NUM_INDIRECT_DRAW_CMD_SIGS);
|
||||
assert(key.value < DZN_NUM_INDIRECT_DRAW_CMD_SIGS);
|
||||
|
||||
struct dzn_device *device =
|
||||
container_of(pipeline->base.base.device, struct dzn_device, vk);
|
||||
ID3D12CommandSignature *cmdsig = pipeline->indirect_cmd_sigs[type];
|
||||
struct dzn_device *device = container_of(pipeline->base.base.device, struct dzn_device, vk);
|
||||
ID3D12CommandSignature *cmdsig = pipeline->indirect_cmd_sigs[key.value];
|
||||
|
||||
if (cmdsig)
|
||||
return cmdsig;
|
||||
|
||||
bool triangle_fan = type == DZN_INDIRECT_DRAW_TRIANGLE_FAN_CMD_SIG;
|
||||
bool indexed = type == DZN_INDIRECT_INDEXED_DRAW_CMD_SIG || triangle_fan;
|
||||
|
||||
uint32_t cmd_arg_count = 0;
|
||||
D3D12_INDIRECT_ARGUMENT_DESC cmd_args[DZN_INDIRECT_CMD_SIG_MAX_ARGS];
|
||||
uint32_t stride = 0;
|
||||
|
||||
if (triangle_fan) {
|
||||
if (key.triangle_fan) {
|
||||
assert(key.indexed);
|
||||
cmd_args[cmd_arg_count++] = (D3D12_INDIRECT_ARGUMENT_DESC) {
|
||||
.Type = D3D12_INDIRECT_ARGUMENT_TYPE_INDEX_BUFFER_VIEW,
|
||||
};
|
||||
stride += sizeof(D3D12_INDEX_BUFFER_VIEW);
|
||||
}
|
||||
|
||||
if (key.draw_params) {
|
||||
cmd_args[cmd_arg_count++] = (D3D12_INDIRECT_ARGUMENT_DESC){
|
||||
.Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT,
|
||||
.Constant = {
|
||||
.RootParameterIndex = pipeline->base.root.sysval_cbv_param_idx,
|
||||
.DestOffsetIn32BitValues = offsetof(struct dxil_spirv_vertex_runtime_data, first_vertex) / 4,
|
||||
.Num32BitValuesToSet = 2,
|
||||
},
|
||||
};
|
||||
stride += sizeof(uint32_t) * 2;
|
||||
}
|
||||
|
||||
if (key.draw_id) {
|
||||
struct dzn_physical_device *pdev = container_of(device->vk.physical, struct dzn_physical_device, vk);
|
||||
if (pdev->options21.ExecuteIndirectTier >= D3D12_EXECUTE_INDIRECT_TIER_1_1) {
|
||||
cmd_args[cmd_arg_count++] = (D3D12_INDIRECT_ARGUMENT_DESC){
|
||||
.Type = D3D12_INDIRECT_ARGUMENT_TYPE_INCREMENTING_CONSTANT,
|
||||
.IncrementingConstant = {
|
||||
.RootParameterIndex = pipeline->base.root.sysval_cbv_param_idx,
|
||||
.DestOffsetIn32BitValues = offsetof(struct dxil_spirv_vertex_runtime_data, draw_id) / 4,
|
||||
},
|
||||
};
|
||||
} else {
|
||||
cmd_args[cmd_arg_count++] = (D3D12_INDIRECT_ARGUMENT_DESC){
|
||||
.Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT,
|
||||
.Constant = {
|
||||
.RootParameterIndex = pipeline->base.root.sysval_cbv_param_idx,
|
||||
.DestOffsetIn32BitValues = offsetof(struct dxil_spirv_vertex_runtime_data, draw_id) / 4,
|
||||
.Num32BitValuesToSet = 1,
|
||||
},
|
||||
};
|
||||
stride += sizeof(uint32_t);
|
||||
}
|
||||
}
|
||||
|
||||
cmd_args[cmd_arg_count++] = (D3D12_INDIRECT_ARGUMENT_DESC) {
|
||||
.Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT,
|
||||
.Constant = {
|
||||
.RootParameterIndex = pipeline->base.root.sysval_cbv_param_idx,
|
||||
.DestOffsetIn32BitValues = offsetof(struct dxil_spirv_vertex_runtime_data, first_vertex) / 4,
|
||||
.Num32BitValuesToSet = 2,
|
||||
},
|
||||
};
|
||||
|
||||
cmd_args[cmd_arg_count++] = (D3D12_INDIRECT_ARGUMENT_DESC) {
|
||||
.Type = D3D12_INDIRECT_ARGUMENT_TYPE_CONSTANT,
|
||||
.Constant = {
|
||||
.RootParameterIndex = pipeline->base.root.sysval_cbv_param_idx,
|
||||
.DestOffsetIn32BitValues = offsetof(struct dxil_spirv_vertex_runtime_data, draw_id) / 4,
|
||||
.Num32BitValuesToSet = 1,
|
||||
},
|
||||
};
|
||||
|
||||
cmd_args[cmd_arg_count++] = (D3D12_INDIRECT_ARGUMENT_DESC) {
|
||||
.Type = indexed ?
|
||||
.Type = key.indexed ?
|
||||
D3D12_INDIRECT_ARGUMENT_TYPE_DRAW_INDEXED :
|
||||
D3D12_INDIRECT_ARGUMENT_TYPE_DRAW,
|
||||
};
|
||||
stride += key.indexed ? sizeof(D3D12_DRAW_INDEXED_ARGUMENTS) :
|
||||
sizeof(D3D12_DRAW_ARGUMENTS);
|
||||
|
||||
assert(cmd_arg_count <= ARRAY_SIZE(cmd_args));
|
||||
assert(offsetof(struct dxil_spirv_vertex_runtime_data, first_vertex) == 0);
|
||||
|
||||
D3D12_COMMAND_SIGNATURE_DESC cmd_sig_desc = {
|
||||
.ByteStride =
|
||||
triangle_fan ?
|
||||
sizeof(struct dzn_indirect_triangle_fan_draw_exec_params) :
|
||||
sizeof(struct dzn_indirect_draw_exec_params),
|
||||
.ByteStride = stride,
|
||||
.NumArgumentDescs = cmd_arg_count,
|
||||
.pArgumentDescs = cmd_args,
|
||||
};
|
||||
/* A root signature should be specified iff root params are changing */
|
||||
ID3D12RootSignature *root_sig = key.draw_id || key.draw_params ?
|
||||
pipeline->base.root.sig : NULL;
|
||||
HRESULT hres =
|
||||
ID3D12Device1_CreateCommandSignature(device->dev, &cmd_sig_desc,
|
||||
pipeline->base.root.sig,
|
||||
root_sig,
|
||||
&IID_ID3D12CommandSignature,
|
||||
(void **)&cmdsig);
|
||||
if (FAILED(hres))
|
||||
return NULL;
|
||||
|
||||
pipeline->indirect_cmd_sigs[type] = cmdsig;
|
||||
pipeline->indirect_cmd_sigs[key.value] = cmdsig;
|
||||
return cmdsig;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -931,12 +931,18 @@ struct dzn_pipeline {
|
|||
|
||||
extern const struct vk_pipeline_cache_object_ops dzn_cached_blob_ops;
|
||||
|
||||
enum dzn_indirect_draw_cmd_sig_type {
|
||||
DZN_INDIRECT_DRAW_CMD_SIG,
|
||||
DZN_INDIRECT_INDEXED_DRAW_CMD_SIG,
|
||||
DZN_INDIRECT_DRAW_TRIANGLE_FAN_CMD_SIG,
|
||||
DZN_NUM_INDIRECT_DRAW_CMD_SIGS,
|
||||
struct dzn_indirect_draw_cmd_sig_key {
|
||||
union {
|
||||
struct {
|
||||
uint8_t indexed : 1;
|
||||
uint8_t draw_params : 1;
|
||||
uint8_t draw_id : 1;
|
||||
uint8_t triangle_fan : 1;
|
||||
};
|
||||
uint8_t value;
|
||||
};
|
||||
};
|
||||
#define DZN_NUM_INDIRECT_DRAW_CMD_SIGS (1 << 4)
|
||||
|
||||
struct dzn_graphics_pipeline {
|
||||
struct dzn_pipeline base;
|
||||
|
|
@ -1031,7 +1037,7 @@ dzn_graphics_pipeline_get_state(struct dzn_graphics_pipeline *pipeline,
|
|||
|
||||
ID3D12CommandSignature *
|
||||
dzn_graphics_pipeline_get_indirect_cmd_sig(struct dzn_graphics_pipeline *pipeline,
|
||||
enum dzn_indirect_draw_cmd_sig_type cmd_sig_type);
|
||||
struct dzn_indirect_draw_cmd_sig_key key);
|
||||
|
||||
VkFormat dzn_graphics_pipeline_patch_vi_format(VkFormat format);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue