diff --git a/src/intel/vulkan/genX_cmd_buffer.c b/src/intel/vulkan/genX_cmd_buffer.c index e3d256ff653..c5fede5d295 100644 --- a/src/intel/vulkan/genX_cmd_buffer.c +++ b/src/intel/vulkan/genX_cmd_buffer.c @@ -4478,12 +4478,8 @@ void genX(CmdDrawIndexedIndirect)( static struct mi_value prepare_for_draw_count_predicate(struct anv_cmd_buffer *cmd_buffer, struct mi_builder *b, - struct anv_buffer *count_buffer, - uint64_t countBufferOffset) + struct anv_address count_address) { - struct anv_address count_address = - anv_address_add(count_buffer->address, countBufferOffset); - struct mi_value ret = mi_imm(0); if (cmd_buffer->state.conditional_render_enabled) { @@ -4557,6 +4553,74 @@ emit_draw_count_predicate_cond(struct anv_cmd_buffer *cmd_buffer, } } +static void +emit_indirect_count_draws(struct anv_cmd_buffer *cmd_buffer, + struct anv_address indirect_data_addr, + uint32_t indirect_data_stride, + struct anv_address draw_count_addr, + uint32_t max_draw_count, + bool indexed) +{ +#if GFX_VER < 11 + struct anv_graphics_pipeline *pipeline = cmd_buffer->state.gfx.pipeline; + const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline); +#endif + + genX(cmd_buffer_flush_gfx_state)(cmd_buffer); + + struct mi_builder b; + mi_builder_init(&b, cmd_buffer->device->info, &cmd_buffer->batch); + struct mi_value max = + prepare_for_draw_count_predicate(cmd_buffer, &b, draw_count_addr); + + for (uint32_t i = 0; i < max_draw_count; i++) { + struct anv_address draw = + anv_address_add(indirect_data_addr, i * indirect_data_stride); + + emit_draw_count_predicate_cond(cmd_buffer, &b, i, max); + +#if GFX_VER < 11 + if (vs_prog_data->uses_firstvertex || + vs_prog_data->uses_baseinstance) { + emit_base_vertex_instance_bo(cmd_buffer, + anv_address_add(draw, indexed ? 12 : 8)); + } + if (vs_prog_data->uses_drawid) + emit_draw_index(cmd_buffer, i); + + /* Emitting draw index or vertex index BOs may result in needing + * additional VF cache flushes. + */ + genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer); +#endif + + load_indirect_parameters(cmd_buffer, draw, indexed, i); + + anv_batch_emit(&cmd_buffer->batch, +#if GFX_VER < 11 + GENX(3DPRIMITIVE), +#else + GENX(3DPRIMITIVE_EXTENDED), +#endif + prim) { + prim.IndirectParameterEnable = true; + prim.PredicateEnable = true; + prim.VertexAccessType = indexed ? RANDOM : SEQUENTIAL; +#if GFX_VER >= 11 + prim.ExtendedParametersPresent = true; +#endif + } + +#if GFX_VERx10 == 125 + genX(emit_dummy_post_sync_op)(cmd_buffer, 1); +#endif + + update_dirty_vbs_for_gfx8_vb_flush(cmd_buffer, SEQUENTIAL); + } + + mi_value_unref(&b, max); +} + void genX(CmdDrawIndirectCount)( VkCommandBuffer commandBuffer, VkBuffer _buffer, @@ -4569,11 +4633,6 @@ void genX(CmdDrawIndirectCount)( ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); ANV_FROM_HANDLE(anv_buffer, buffer, _buffer); ANV_FROM_HANDLE(anv_buffer, count_buffer, _countBuffer); -#if GFX_VER < 11 - struct anv_cmd_state *cmd_state = &cmd_buffer->state; - struct anv_graphics_pipeline *pipeline = cmd_state->gfx.pipeline; - const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline); -#endif if (anv_batch_has_error(&cmd_buffer->batch)) return; @@ -4584,59 +4643,12 @@ void genX(CmdDrawIndirectCount)( 0); trace_intel_begin_draw_indirect_count(&cmd_buffer->trace); - genX(cmd_buffer_flush_gfx_state)(cmd_buffer); - - struct mi_builder b; - mi_builder_init(&b, cmd_buffer->device->info, &cmd_buffer->batch); - struct mi_value max = - prepare_for_draw_count_predicate(cmd_buffer, &b, - count_buffer, countBufferOffset); - - for (uint32_t i = 0; i < maxDrawCount; i++) { - struct anv_address draw = anv_address_add(buffer->address, offset); - - emit_draw_count_predicate_cond(cmd_buffer, &b, i, max); - -#if GFX_VER < 11 - if (vs_prog_data->uses_firstvertex || - vs_prog_data->uses_baseinstance) - emit_base_vertex_instance_bo(cmd_buffer, anv_address_add(draw, 8)); - if (vs_prog_data->uses_drawid) - emit_draw_index(cmd_buffer, i); -#endif - - /* Emitting draw index or vertex index BOs may result in needing - * additional VF cache flushes. - */ - genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer); - - load_indirect_parameters(cmd_buffer, draw, false, i); - - anv_batch_emit(&cmd_buffer->batch, -#if GFX_VER < 11 - GENX(3DPRIMITIVE), -#else - GENX(3DPRIMITIVE_EXTENDED), -#endif - prim) { - prim.IndirectParameterEnable = true; - prim.PredicateEnable = true; - prim.VertexAccessType = SEQUENTIAL; -#if GFX_VER >= 11 - prim.ExtendedParametersPresent = true; -#endif - } - -#if GFX_VERx10 == 125 - genX(emit_dummy_post_sync_op)(cmd_buffer, 1); -#endif - - update_dirty_vbs_for_gfx8_vb_flush(cmd_buffer, SEQUENTIAL); - - offset += stride; - } - - mi_value_unref(&b, max); + emit_indirect_count_draws(cmd_buffer, + anv_address_add(buffer->address, offset), + MAX2(stride, sizeof(VkDrawIndirectCommand)), + anv_address_add(count_buffer->address, countBufferOffset), + maxDrawCount, + false /* indexed */); trace_intel_end_draw_indirect_count(&cmd_buffer->trace, maxDrawCount); } @@ -4653,11 +4665,6 @@ void genX(CmdDrawIndexedIndirectCount)( ANV_FROM_HANDLE(anv_cmd_buffer, cmd_buffer, commandBuffer); ANV_FROM_HANDLE(anv_buffer, buffer, _buffer); ANV_FROM_HANDLE(anv_buffer, count_buffer, _countBuffer); -#if GFX_VER < 11 - struct anv_cmd_state *cmd_state = &cmd_buffer->state; - struct anv_graphics_pipeline *pipeline = cmd_state->gfx.pipeline; - const struct brw_vs_prog_data *vs_prog_data = get_vs_prog_data(pipeline); -#endif if (anv_batch_has_error(&cmd_buffer->batch)) return; @@ -4668,60 +4675,12 @@ void genX(CmdDrawIndexedIndirectCount)( 0); trace_intel_begin_draw_indexed_indirect_count(&cmd_buffer->trace); - genX(cmd_buffer_flush_gfx_state)(cmd_buffer); - - struct mi_builder b; - mi_builder_init(&b, cmd_buffer->device->info, &cmd_buffer->batch); - struct mi_value max = - prepare_for_draw_count_predicate(cmd_buffer, &b, - count_buffer, countBufferOffset); - - for (uint32_t i = 0; i < maxDrawCount; i++) { - struct anv_address draw = anv_address_add(buffer->address, offset); - - emit_draw_count_predicate_cond(cmd_buffer, &b, i, max); - -#if GFX_VER < 11 - /* TODO: We need to stomp base vertex to 0 somehow */ - if (vs_prog_data->uses_firstvertex || - vs_prog_data->uses_baseinstance) - emit_base_vertex_instance_bo(cmd_buffer, anv_address_add(draw, 12)); - if (vs_prog_data->uses_drawid) - emit_draw_index(cmd_buffer, i); -#endif - - /* Emitting draw index or vertex index BOs may result in needing - * additional VF cache flushes. - */ - genX(cmd_buffer_apply_pipe_flushes)(cmd_buffer); - - load_indirect_parameters(cmd_buffer, draw, true, i); - - anv_batch_emit(&cmd_buffer->batch, -#if GFX_VER < 11 - GENX(3DPRIMITIVE), -#else - GENX(3DPRIMITIVE_EXTENDED), -#endif - prim) { - prim.IndirectParameterEnable = true; - prim.PredicateEnable = true; - prim.VertexAccessType = RANDOM; -#if GFX_VER >= 11 - prim.ExtendedParametersPresent = true; -#endif - } - -#if GFX_VERx10 == 125 - genX(emit_dummy_post_sync_op)(cmd_buffer, 1); -#endif - - update_dirty_vbs_for_gfx8_vb_flush(cmd_buffer, RANDOM); - - offset += stride; - } - - mi_value_unref(&b, max); + emit_indirect_count_draws(cmd_buffer, + anv_address_add(buffer->address, offset), + MAX2(stride, sizeof(VkDrawIndirectCommand)), + anv_address_add(count_buffer->address, countBufferOffset), + maxDrawCount, + true /* indexed */); trace_intel_end_draw_indexed_indirect_count(&cmd_buffer->trace, maxDrawCount); @@ -5115,8 +5074,9 @@ genX(CmdDrawMeshTasksIndirectCountNV)( mi_builder_init(&b, cmd_buffer->device->info, &cmd_buffer->batch); struct mi_value max = - prepare_for_draw_count_predicate(cmd_buffer, &b, - count_buffer, countBufferOffset); + prepare_for_draw_count_predicate( + cmd_buffer, &b, + anv_address_add(count_buffer->address, countBufferOffset)); for (uint32_t i = 0; i < maxDrawCount; i++) { struct anv_address draw = anv_address_add(buffer->address, offset); @@ -5168,8 +5128,9 @@ genX(CmdDrawMeshTasksIndirectCountEXT)( mi_builder_init(&b, cmd_buffer->device->info, &cmd_buffer->batch); struct mi_value max = - prepare_for_draw_count_predicate(cmd_buffer, &b, - count_buffer, countBufferOffset); + prepare_for_draw_count_predicate( + cmd_buffer, &b, + anv_address_add(count_buffer->address, countBufferOffset)); for (uint32_t i = 0; i < maxDrawCount; i++) { struct anv_address draw = anv_address_add(buffer->address, offset);