diff --git a/src/microsoft/ci/warp-fails.txt b/src/microsoft/ci/warp-fails.txt index 6922d1f7fc8..2517cd58a79 100644 --- a/src/microsoft/ci/warp-fails.txt +++ b/src/microsoft/ci/warp-fails.txt @@ -874,6 +874,14 @@ dEQP-VK.api.copy_and_blit.dedicated_allocation.blit_image.all_formats.depth_sten dEQP-VK.api.copy_and_blit.dedicated_allocation.blit_image.all_formats.depth_stencil.2d.d32_sfloat_s8_uint_d32_sfloat_s8_uint_separate_layouts.general_optimal_nearest,Fail dEQP-VK.api.copy_and_blit.dedicated_allocation.blit_image.all_formats.depth_stencil.2d.d32_sfloat_s8_uint_d32_sfloat_s8_uint_separate_layouts.optimal_general_nearest,Fail dEQP-VK.api.copy_and_blit.dedicated_allocation.blit_image.all_formats.depth_stencil.2d.d32_sfloat_s8_uint_d32_sfloat_s8_uint_separate_layouts.optimal_optimal_nearest,Fail +dEQP-VK.draw.dynamic_rendering.basic_draw.draw_indexed_indirect.triangle_fan.45_multi_command,Fail +dEQP-VK.draw.dynamic_rendering.basic_draw.draw_indirect.triangle_fan.45_multi_command,Fail +dEQP-VK.draw.renderpass.basic_draw.draw_indexed_indirect.triangle_fan.17_multi_command,Fail +dEQP-VK.draw.renderpass.basic_draw.draw_indexed_indirect.triangle_fan.3_multi_command,Fail +dEQP-VK.draw.renderpass.basic_draw.draw_indexed_indirect.triangle_fan.45_multi_command,Fail +dEQP-VK.draw.renderpass.basic_draw.draw_indirect.triangle_fan.17_multi_command,Fail +dEQP-VK.draw.renderpass.basic_draw.draw_indirect.triangle_fan.3_multi_command,Fail +dEQP-VK.draw.renderpass.basic_draw.draw_indirect.triangle_fan.45_multi_command,Fail dEQP-VK.draw.renderpass.multiple_interpolation.separate.no_sample_decoration.4_samples,Fail dEQP-VK.draw.renderpass.multiple_interpolation.separate.with_sample_decoration.4_samples,Fail dEQP-VK.draw.renderpass.multiple_interpolation.structured.no_sample_decoration.4_samples,Fail diff --git a/src/microsoft/vulkan/dzn_cmd_buffer.c b/src/microsoft/vulkan/dzn_cmd_buffer.c index 9bd9bb37f40..902b0546349 100644 --- a/src/microsoft/vulkan/dzn_cmd_buffer.c +++ b/src/microsoft/vulkan/dzn_cmd_buffer.c @@ -2547,7 +2547,9 @@ static void dzn_cmd_buffer_indirect_draw(struct dzn_cmd_buffer *cmdbuf, struct dzn_buffer *draw_buf, size_t draw_buf_offset, - uint32_t draw_count, + struct dzn_buffer *count_buf, + size_t count_buf_offset, + uint32_t max_draw_count, uint32_t draw_buf_stride, bool indexed) { @@ -2574,9 +2576,19 @@ dzn_cmd_buffer_indirect_draw(struct dzn_cmd_buffer *cmdbuf, sizeof(struct dzn_indirect_draw_exec_params); 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; + uint32_t exec_buf_draw_offset = 0; + + // We reserve the first slot for the draw_count value when indirect count is + // involved. + if (count_buf != NULL) { + exec_buf_size += exec_buf_stride; + exec_buf_draw_offset = exec_buf_stride; + } + ID3D12Resource *exec_buf; VkResult result = - dzn_cmd_buffer_alloc_internal_buf(cmdbuf, draw_count * exec_buf_stride, + dzn_cmd_buffer_alloc_internal_buf(cmdbuf, exec_buf_size, D3D12_HEAP_TYPE_DEFAULT, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, &exec_buf); @@ -2591,7 +2603,7 @@ dzn_cmd_buffer_indirect_draw(struct dzn_cmd_buffer *cmdbuf, if (triangle_fan_index_buf_stride) { result = dzn_cmd_buffer_alloc_internal_buf(cmdbuf, - draw_count * triangle_fan_index_buf_stride, + max_draw_count * triangle_fan_index_buf_stride, D3D12_HEAP_TYPE_DEFAULT, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, &triangle_fan_index_buf); @@ -2600,7 +2612,7 @@ dzn_cmd_buffer_indirect_draw(struct dzn_cmd_buffer *cmdbuf, result = dzn_cmd_buffer_alloc_internal_buf(cmdbuf, - draw_count * triangle_fan_exec_buf_stride, + max_draw_count * triangle_fan_exec_buf_stride, D3D12_HEAP_TYPE_DEFAULT, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, &triangle_fan_exec_buf); @@ -2622,29 +2634,50 @@ dzn_cmd_buffer_indirect_draw(struct dzn_cmd_buffer *cmdbuf, enum dzn_indirect_draw_type draw_type; - if (indexed && triangle_fan_index_buf_stride > 0) - draw_type = DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN; - else if (!indexed && triangle_fan_index_buf_stride > 0) - draw_type = DZN_INDIRECT_DRAW_TRIANGLE_FAN; - else if (indexed) - draw_type = DZN_INDIRECT_INDEXED_DRAW; - else - draw_type = DZN_INDIRECT_DRAW; + if (indexed && triangle_fan_index_buf_stride > 0) { + draw_type = count_buf ? + DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN : + 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]; const struct dzn_pipeline *compute_pipeline = cmdbuf->state.bindpoint[VK_PIPELINE_BIND_POINT_COMPUTE].pipeline; + uint32_t root_param_idx = 0; ID3D12GraphicsCommandList1_SetComputeRootSignature(cmdbuf->cmdlist, indirect_draw->root_sig); ID3D12GraphicsCommandList1_SetPipelineState(cmdbuf->cmdlist, indirect_draw->pipeline_state); - ID3D12GraphicsCommandList1_SetComputeRoot32BitConstants(cmdbuf->cmdlist, 0, params_size / 4, ¶ms, 0); - ID3D12GraphicsCommandList1_SetComputeRootShaderResourceView(cmdbuf->cmdlist, 1, draw_buf_gpu); - ID3D12GraphicsCommandList1_SetComputeRootUnorderedAccessView(cmdbuf->cmdlist, 2, ID3D12Resource_GetGPUVirtualAddress(exec_buf)); - if (triangle_fan_exec_buf) - ID3D12GraphicsCommandList1_SetComputeRootUnorderedAccessView(cmdbuf->cmdlist, 3, ID3D12Resource_GetGPUVirtualAddress(triangle_fan_exec_buf)); + ID3D12GraphicsCommandList1_SetComputeRoot32BitConstants(cmdbuf->cmdlist, root_param_idx++, + params_size / 4, (const void *)¶ms, 0); + ID3D12GraphicsCommandList1_SetComputeRootShaderResourceView(cmdbuf->cmdlist, root_param_idx++, + draw_buf_gpu); + ID3D12GraphicsCommandList1_SetComputeRootUnorderedAccessView(cmdbuf->cmdlist, root_param_idx++, + ID3D12Resource_GetGPUVirtualAddress(exec_buf)); + if (count_buf) { + ID3D12GraphicsCommandList1_SetComputeRootShaderResourceView(cmdbuf->cmdlist, + root_param_idx++, + ID3D12Resource_GetGPUVirtualAddress(count_buf->res) + + count_buf_offset); + } - ID3D12GraphicsCommandList1_Dispatch(cmdbuf->cmdlist, draw_count, 1, 1); + if (triangle_fan_exec_buf) { + ID3D12GraphicsCommandList1_SetComputeRootUnorderedAccessView(cmdbuf->cmdlist, + root_param_idx++, + ID3D12Resource_GetGPUVirtualAddress(triangle_fan_exec_buf)); + } + + ID3D12GraphicsCommandList1_Dispatch(cmdbuf->cmdlist, max_draw_count, 1, 1); D3D12_RESOURCE_BARRIER post_barriers[] = { { @@ -2697,16 +2730,22 @@ dzn_cmd_buffer_indirect_draw(struct dzn_cmd_buffer *cmdbuf, ID3D12GraphicsCommandList1_SetComputeRootSignature(cmdbuf->cmdlist, rewrite_index->root_sig); ID3D12GraphicsCommandList1_SetPipelineState(cmdbuf->cmdlist, rewrite_index->pipeline_state); - ID3D12GraphicsCommandList1_SetComputeRootUnorderedAccessView(cmdbuf->cmdlist, 0, ID3D12Resource_GetGPUVirtualAddress(triangle_fan_index_buf)); - ID3D12GraphicsCommandList1_SetComputeRoot32BitConstants(cmdbuf->cmdlist, 1, sizeof(rewrite_index_params) / 4, + root_param_idx = 0; + ID3D12GraphicsCommandList1_SetComputeRootUnorderedAccessView(cmdbuf->cmdlist, root_param_idx++, + ID3D12Resource_GetGPUVirtualAddress(triangle_fan_index_buf)); + ID3D12GraphicsCommandList1_SetComputeRoot32BitConstants(cmdbuf->cmdlist, root_param_idx++, + sizeof(rewrite_index_params) / 4, (const void *)&rewrite_index_params, 0); - if (indexed) - ID3D12GraphicsCommandList1_SetComputeRootShaderResourceView(cmdbuf->cmdlist, 2, cmdbuf->state.ib.view.BufferLocation); + if (indexed) { + ID3D12GraphicsCommandList1_SetComputeRootShaderResourceView(cmdbuf->cmdlist, + root_param_idx++, + cmdbuf->state.ib.view.BufferLocation); + } ID3D12GraphicsCommandList1_ExecuteIndirect(cmdbuf->cmdlist, rewrite_index->cmd_sig, - draw_count, triangle_fan_exec_buf, - 0, NULL, 0); + max_draw_count, triangle_fan_exec_buf, 0, + count_buf ? exec_buf : NULL, 0); D3D12_RESOURCE_BARRIER index_buf_barriers[] = { { @@ -2771,7 +2810,9 @@ dzn_cmd_buffer_indirect_draw(struct dzn_cmd_buffer *cmdbuf, } ID3D12GraphicsCommandList1_ExecuteIndirect(cmdbuf->cmdlist, cmdsig, - draw_count, exec_buf, 0, NULL, 0); + max_draw_count, + exec_buf, exec_buf_draw_offset, + count_buf ? exec_buf : NULL, 0); } static void @@ -3729,7 +3770,7 @@ dzn_CmdDrawIndirect(VkCommandBuffer commandBuffer, VK_FROM_HANDLE(dzn_cmd_buffer, cmdbuf, commandBuffer); VK_FROM_HANDLE(dzn_buffer, buf, buffer); - dzn_cmd_buffer_indirect_draw(cmdbuf, buf, offset, drawCount, stride, false); + dzn_cmd_buffer_indirect_draw(cmdbuf, buf, offset, NULL, 0, drawCount, stride, false); } VKAPI_ATTR void VKAPI_CALL @@ -3742,7 +3783,43 @@ dzn_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, VK_FROM_HANDLE(dzn_cmd_buffer, cmdbuf, commandBuffer); VK_FROM_HANDLE(dzn_buffer, buf, buffer); - dzn_cmd_buffer_indirect_draw(cmdbuf, buf, offset, drawCount, stride, true); + dzn_cmd_buffer_indirect_draw(cmdbuf, buf, offset, NULL, 0, drawCount, stride, true); +} + +VKAPI_ATTR void VKAPI_CALL +dzn_CmdDrawIndirectCount(VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride) +{ + VK_FROM_HANDLE(dzn_cmd_buffer, cmdbuf, commandBuffer); + VK_FROM_HANDLE(dzn_buffer, buf, buffer); + VK_FROM_HANDLE(dzn_buffer, count_buf, countBuffer); + + dzn_cmd_buffer_indirect_draw(cmdbuf, buf, offset, + count_buf, countBufferOffset, + maxDrawCount, stride, false); +} + +VKAPI_ATTR void VKAPI_CALL +dzn_CmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride) +{ + VK_FROM_HANDLE(dzn_cmd_buffer, cmdbuf, commandBuffer); + VK_FROM_HANDLE(dzn_buffer, buf, buffer); + VK_FROM_HANDLE(dzn_buffer, count_buf, countBuffer); + + dzn_cmd_buffer_indirect_draw(cmdbuf, buf, offset, + count_buf, countBufferOffset, + maxDrawCount, stride, true); } VKAPI_ATTR void VKAPI_CALL diff --git a/src/microsoft/vulkan/dzn_device.c b/src/microsoft/vulkan/dzn_device.c index 69dd7d221ff..989919aab3e 100644 --- a/src/microsoft/vulkan/dzn_device.c +++ b/src/microsoft/vulkan/dzn_device.c @@ -78,6 +78,7 @@ dzn_physical_device_get_extensions(struct dzn_physical_device *pdev) { pdev->vk.supported_extensions = (struct vk_device_extension_table) { .KHR_descriptor_update_template = true, + .KHR_draw_indirect_count = true, .KHR_dynamic_rendering = true, .KHR_shader_draw_parameters = true, #ifdef DZN_USE_WSI_PLATFORM diff --git a/src/microsoft/vulkan/dzn_meta.c b/src/microsoft/vulkan/dzn_meta.c index 9ecc4fbefa0..d0e88dbab9b 100644 --- a/src/microsoft/vulkan/dzn_meta.c +++ b/src/microsoft/vulkan/dzn_meta.c @@ -87,7 +87,7 @@ dzn_meta_compile_shader(struct dzn_device *device, nir_shader *nir, slot->BytecodeLength = size; } -#define DZN_META_INDIRECT_DRAW_MAX_PARAM_COUNT 4 +#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) @@ -114,7 +114,13 @@ dzn_meta_indirect_draw_init(struct dzn_device *device, nir_shader *nir = dzn_nir_indirect_draw_shader(type); bool triangle_fan = type == DZN_INDIRECT_DRAW_TRIANGLE_FAN || - type == DZN_INDIRECT_INDEXED_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; + 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; uint32_t shader_params_size = triangle_fan ? sizeof(struct dzn_indirect_draw_triangle_fan_rewrite_params) : @@ -153,12 +159,24 @@ dzn_meta_indirect_draw_init(struct dzn_device *device, .ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL, }; + if (indirect_count) { + root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) { + .ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV, + .Descriptor = { + .ShaderRegister = 3, + .RegisterSpace = 0, + .Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + }, + .ShaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + }; + } + if (triangle_fan) { root_params[root_param_count++] = (D3D12_ROOT_PARAMETER1) { .ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV, .Descriptor = { - .ShaderRegister = 3, + .ShaderRegister = 4, .RegisterSpace = 0, .Flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, }, diff --git a/src/microsoft/vulkan/dzn_nir.c b/src/microsoft/vulkan/dzn_nir.c index 146322756a1..fcae26f45b7 100644 --- a/src/microsoft/vulkan/dzn_nir.c +++ b/src/microsoft/vulkan/dzn_nir.c @@ -86,17 +86,29 @@ dzn_nir_indirect_draw_shader(enum 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", }; assert(type < ARRAY_SIZE(type_str)); bool indexed = type == DZN_INDIRECT_INDEXED_DRAW || - type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN; + type == DZN_INDIRECT_INDEXED_DRAW_COUNT || + type == DZN_INDIRECT_INDEXED_DRAW_TRIANGLE_FAN || + type == DZN_INDIRECT_INDEXED_DRAW_COUNT_TRIANGLE_FAN; bool triangle_fan = type == DZN_INDIRECT_DRAW_TRIANGLE_FAN || - type == DZN_INDIRECT_INDEXED_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; + 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; nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_COMPUTE, dxil_get_nir_compiler_options(), @@ -136,8 +148,29 @@ dzn_nir_indirect_draw_shader(enum dzn_indirect_draw_type type) nir_ssa_def *index = nir_channel(&b, nir_load_global_invocation_id(&b, 32), 0); + if (indirect_count) { + nir_ssa_def *count_buf_desc = + dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 3, "count_buf", ACCESS_NON_WRITEABLE); + + nir_ssa_def *draw_count = + nir_load_ssbo(&b, 1, 32, count_buf_desc, nir_imm_int(&b, 0), .align_mul = 4); + + nir_push_if(&b, nir_ieq(&b, index, nir_imm_int(&b, 0))); + nir_store_ssbo(&b, draw_count, exec_buf_desc, nir_imm_int(&b, 0), + .write_mask = 0x1, .access = ACCESS_NON_READABLE, + .align_mul = 16); + nir_pop_if(&b, NULL); + + nir_push_if(&b, nir_ult(&b, index, draw_count)); + } + nir_ssa_def *draw_offset = nir_imul(&b, draw_stride, index); - nir_ssa_def *exec_offset = nir_imul(&b, exec_stride, index); + + /* The first entry contains the indirect count */ + nir_ssa_def *exec_offset = + indirect_count ? + nir_imul(&b, exec_stride, nir_iadd_imm(&b, index, 1)) : + nir_imul(&b, exec_stride, index); nir_ssa_def *draw_info1 = nir_load_ssbo(&b, 4, 32, draw_buf_desc, draw_offset, .align_mul = 4); @@ -168,7 +201,7 @@ dzn_nir_indirect_draw_shader(enum dzn_indirect_draw_type type) exec_vals[7] = base_instance; nir_ssa_def *triangle_fan_exec_buf_desc = - dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 3, + dzn_nir_create_bo_desc(&b, nir_var_mem_ssbo, 0, 4, "triangle_fan_exec_buf", ACCESS_NON_READABLE); nir_ssa_def *triangle_fan_index_buf_stride = nir_channel(&b, params, 1); @@ -232,6 +265,8 @@ dzn_nir_indirect_draw_shader(enum dzn_indirect_draw_type type) exec_buf_desc, nir_iadd_imm(&b, exec_offset, 16), .write_mask = 0xf, .access = ACCESS_NON_READABLE, .align_mul = 16); + if (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 d05f1ba5030..8e095ddb040 100644 --- a/src/microsoft/vulkan/dzn_nir.h +++ b/src/microsoft/vulkan/dzn_nir.h @@ -94,9 +94,13 @@ struct dzn_indirect_triangle_fan_rewrite_index_exec_params { 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_NUM_INDIRECT_DRAW_TYPES, };