diff --git a/src/microsoft/vulkan/dzn_cmd_buffer.c b/src/microsoft/vulkan/dzn_cmd_buffer.c index 5f3a1fdbf24..7ebce7df694 100644 --- a/src/microsoft/vulkan/dzn_cmd_buffer.c +++ b/src/microsoft/vulkan/dzn_cmd_buffer.c @@ -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); diff --git a/src/microsoft/vulkan/dzn_meta.c b/src/microsoft/vulkan/dzn_meta.c index 8fd19a45f6d..5f5cfe75295 100644 --- a/src/microsoft/vulkan/dzn_meta.c +++ b/src/microsoft/vulkan/dzn_meta.c @@ -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: diff --git a/src/microsoft/vulkan/dzn_nir.c b/src/microsoft/vulkan/dzn_nir.c index 3007a228264..0d1fea2976f 100644 --- a/src/microsoft/vulkan/dzn_nir.c +++ b/src/microsoft/vulkan/dzn_nir.c @@ -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; diff --git a/src/microsoft/vulkan/dzn_nir.h b/src/microsoft/vulkan/dzn_nir.h index 9dcbf9072c1..afa5cb5958a 100644 --- a/src/microsoft/vulkan/dzn_nir.h +++ b/src/microsoft/vulkan/dzn_nir.h @@ -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); diff --git a/src/microsoft/vulkan/dzn_pipeline.c b/src/microsoft/vulkan/dzn_pipeline.c index b0eab33e88e..dc197f95035 100644 --- a/src/microsoft/vulkan/dzn_pipeline.c +++ b/src/microsoft/vulkan/dzn_pipeline.c @@ -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; } diff --git a/src/microsoft/vulkan/dzn_private.h b/src/microsoft/vulkan/dzn_private.h index 97d59807336..fe1c5869091 100644 --- a/src/microsoft/vulkan/dzn_private.h +++ b/src/microsoft/vulkan/dzn_private.h @@ -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);