X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fvulkan%2Fradv_cmd_buffer.c;h=6a89d4e568d96219b844faadc6eee16c57be682d;hb=34d23e82ca9dce784e3041488725aa828f847f13;hp=04b8147df8ac9f538f0e5c9604aed5e0c34f4648;hpb=403a3d80613fcc7ce0684f763b08a0e33a12374a;p=mesa.git diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 04b8147df8a..6a89d4e568d 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -292,6 +292,8 @@ radv_reset_cmd_buffer(struct radv_cmd_buffer *cmd_buffer) cmd_buffer->gfx9_fence_bo = cmd_buffer->upload.upload_bo; } + cmd_buffer->status = RADV_CMD_BUFFER_STATUS_INITIAL; + return cmd_buffer->record_result; } @@ -591,7 +593,8 @@ radv_update_multisample_state(struct radv_cmd_buffer *cmd_buffer, radeon_set_context_reg(cmd_buffer->cs, R_028804_DB_EQAA, ms->db_eqaa); radeon_set_context_reg(cmd_buffer->cs, R_028A4C_PA_SC_MODE_CNTL_1, ms->pa_sc_mode_cntl_1); - if (old_pipeline && num_samples == old_pipeline->graphics.ms.num_samples) + if (old_pipeline && num_samples == old_pipeline->graphics.ms.num_samples && + old_pipeline->shaders[MESA_SHADER_FRAGMENT]->info.info.ps.needs_sample_positions == pipeline->shaders[MESA_SHADER_FRAGMENT]->info.info.ps.needs_sample_positions) return; radeon_set_context_reg_seq(cmd_buffer->cs, R_028BDC_PA_SC_LINE_CNTL, 2); @@ -1181,9 +1184,10 @@ radv_emit_depth_biais(struct radv_cmd_buffer *cmd_buffer) static void radv_emit_fb_color_state(struct radv_cmd_buffer *cmd_buffer, int index, - struct radv_color_buffer_info *cb) + struct radv_attachment_info *att) { bool is_vi = cmd_buffer->device->physical_device->rad_info.chip_class >= VI; + struct radv_color_buffer_info *cb = &att->cb; if (cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9) { radeon_set_context_reg_seq(cmd_buffer->cs, R_028C60_CB_COLOR0_BASE + index * 0x3c, 11); @@ -1204,7 +1208,7 @@ radv_emit_fb_color_state(struct radv_cmd_buffer *cmd_buffer, radeon_emit(cmd_buffer->cs, cb->cb_dcc_base >> 32); radeon_set_context_reg(cmd_buffer->cs, R_0287A0_CB_MRT0_EPITCH + index * 4, - cb->gfx9_epitch); + S_0287A0_EPITCH(att->attachment->image->surface.u.gfx9.surf.epitch)); } else { radeon_set_context_reg_seq(cmd_buffer->cs, R_028C60_CB_COLOR0_BASE + index * 0x3c, 11); radeon_emit(cmd_buffer->cs, cb->cb_color_base); @@ -1297,8 +1301,7 @@ radv_set_depth_clear_regs(struct radv_cmd_buffer *cmd_buffer, va += image->offset + image->clear_value_offset; unsigned reg_offset = 0, reg_count = 0; - if (!image->surface.htile_size) - return; + assert(image->surface.htile_size); if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { ++reg_count; @@ -1309,8 +1312,6 @@ radv_set_depth_clear_regs(struct radv_cmd_buffer *cmd_buffer, if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) ++reg_count; - radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, image->bo, 8); - radeon_emit(cmd_buffer->cs, PKT3(PKT3_WRITE_DATA, 2 + reg_count, 0)); radeon_emit(cmd_buffer->cs, S_370_DST_SEL(V_370_MEM_ASYNC) | S_370_WR_CONFIRM(1) | @@ -1333,20 +1334,30 @@ static void radv_load_depth_clear_regs(struct radv_cmd_buffer *cmd_buffer, struct radv_image *image) { + VkImageAspectFlags aspects = vk_format_aspects(image->vk_format); uint64_t va = radv_buffer_get_va(image->bo); va += image->offset + image->clear_value_offset; + unsigned reg_offset = 0, reg_count = 0; if (!image->surface.htile_size) return; + if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { + ++reg_count; + } else { + ++reg_offset; + va += 4; + } + if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) + ++reg_count; radeon_emit(cmd_buffer->cs, PKT3(PKT3_COPY_DATA, 4, 0)); radeon_emit(cmd_buffer->cs, COPY_DATA_SRC_SEL(COPY_DATA_MEM) | COPY_DATA_DST_SEL(COPY_DATA_REG) | - COPY_DATA_COUNT_SEL); + (reg_count == 2 ? COPY_DATA_COUNT_SEL : 0)); radeon_emit(cmd_buffer->cs, va); radeon_emit(cmd_buffer->cs, va >> 32); - radeon_emit(cmd_buffer->cs, R_028028_DB_STENCIL_CLEAR >> 2); + radeon_emit(cmd_buffer->cs, (R_028028_DB_STENCIL_CLEAR + 4 * reg_offset) >> 2); radeon_emit(cmd_buffer->cs, 0); radeon_emit(cmd_buffer->cs, PKT3(PKT3_PFP_SYNC_ME, 0, 0)); @@ -1367,8 +1378,7 @@ radv_set_dcc_need_cmask_elim_pred(struct radv_cmd_buffer *cmd_buffer, uint64_t va = radv_buffer_get_va(image->bo); va += image->offset + image->dcc_pred_offset; - if (!image->surface.dcc_size) - return; + assert(image->surface.dcc_size); radeon_emit(cmd_buffer->cs, PKT3(PKT3_WRITE_DATA, 4, 0)); radeon_emit(cmd_buffer->cs, S_370_DST_SEL(V_370_MEM_ASYNC) | @@ -1389,8 +1399,7 @@ radv_set_color_clear_regs(struct radv_cmd_buffer *cmd_buffer, uint64_t va = radv_buffer_get_va(image->bo); va += image->offset + image->clear_value_offset; - if (!image->cmask.size && !image->surface.dcc_size) - return; + assert(image->cmask.size || image->surface.dcc_size); radeon_emit(cmd_buffer->cs, PKT3(PKT3_WRITE_DATA, 4, 0)); radeon_emit(cmd_buffer->cs, S_370_DST_SEL(V_370_MEM_ASYNC) | @@ -1456,7 +1465,7 @@ radv_emit_framebuffer_state(struct radv_cmd_buffer *cmd_buffer) radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, att->attachment->bo, 8); assert(att->attachment->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT); - radv_emit_fb_color_state(cmd_buffer, i, &att->cb); + radv_emit_fb_color_state(cmd_buffer, i, att); radv_load_color_clear_regs(cmd_buffer, att->attachment->image, i); } @@ -1506,21 +1515,26 @@ static void radv_emit_index_buffer(struct radv_cmd_buffer *cmd_buffer) { struct radeon_winsys_cs *cs = cmd_buffer->cs; + struct radv_cmd_state *state = &cmd_buffer->state; - if (cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9) { - radeon_set_uconfig_reg_idx(cs, R_03090C_VGT_INDEX_TYPE, - 2, cmd_buffer->state.index_type); - } else { - radeon_emit(cs, PKT3(PKT3_INDEX_TYPE, 0, 0)); - radeon_emit(cs, cmd_buffer->state.index_type); + if (state->index_type != state->last_index_type) { + if (cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9) { + radeon_set_uconfig_reg_idx(cs, R_03090C_VGT_INDEX_TYPE, + 2, state->index_type); + } else { + radeon_emit(cs, PKT3(PKT3_INDEX_TYPE, 0, 0)); + radeon_emit(cs, state->index_type); + } + + state->last_index_type = state->index_type; } radeon_emit(cs, PKT3(PKT3_INDEX_BASE, 1, 0)); - radeon_emit(cs, cmd_buffer->state.index_va); - radeon_emit(cs, cmd_buffer->state.index_va >> 32); + radeon_emit(cs, state->index_va); + radeon_emit(cs, state->index_va >> 32); radeon_emit(cs, PKT3(PKT3_INDEX_BUFFER_SIZE, 0, 0)); - radeon_emit(cs, cmd_buffer->state.max_index_count); + radeon_emit(cs, state->max_index_count); cmd_buffer->state.dirty &= ~RADV_CMD_DIRTY_INDEX_BUFFER; } @@ -1740,7 +1754,8 @@ radv_flush_constants(struct radv_cmd_buffer *cmd_buffer, uint64_t va; stages &= cmd_buffer->push_constant_stages; - if (!stages || !layout || (!layout->push_constant_size && !layout->dynamic_offset_count)) + if (!stages || + (!layout->push_constant_size && !layout->dynamic_offset_count)) return; if (!radv_cmd_buffer_upload_alloc(cmd_buffer, layout->push_constant_size + @@ -2152,10 +2167,23 @@ VkResult radv_AllocateCommandBuffers( break; } - if (result != VK_SUCCESS) + if (result != VK_SUCCESS) { radv_FreeCommandBuffers(_device, pAllocateInfo->commandPool, i, pCommandBuffers); + /* From the Vulkan 1.0.66 spec: + * + * "vkAllocateCommandBuffers can be used to create multiple + * command buffers. If the creation of any of those command + * buffers fails, the implementation must destroy all + * successfully created command buffer objects from this + * command, set all entries of the pCommandBuffers array to + * NULL and return the error." + */ + memset(pCommandBuffers, 0, + sizeof(*pCommandBuffers) * pAllocateInfo->commandBufferCount); + } + return result; } @@ -2206,14 +2234,20 @@ VkResult radv_BeginCommandBuffer( const VkCommandBufferBeginInfo *pBeginInfo) { RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer); - VkResult result; + VkResult result = VK_SUCCESS; - result = radv_reset_cmd_buffer(cmd_buffer); - if (result != VK_SUCCESS) - return result; + if (cmd_buffer->status != RADV_CMD_BUFFER_STATUS_INITIAL) { + /* If the command buffer has already been resetted with + * vkResetCommandBuffer, no need to do it again. + */ + result = radv_reset_cmd_buffer(cmd_buffer); + if (result != VK_SUCCESS) + return result; + } memset(&cmd_buffer->state, 0, sizeof(cmd_buffer->state)); cmd_buffer->state.last_primitive_reset_en = -1; + cmd_buffer->state.last_index_type = -1; cmd_buffer->usage_flags = pBeginInfo->flags; /* setup initial configuration into command buffer */ @@ -2249,6 +2283,8 @@ VkResult radv_BeginCommandBuffer( if (unlikely(cmd_buffer->device->trace_bo)) radv_cmd_buffer_trace_emit(cmd_buffer); + cmd_buffer->status = RADV_CMD_BUFFER_STATUS_RECORDING; + return result; } @@ -2517,6 +2553,8 @@ VkResult radv_EndCommandBuffer( if (!cmd_buffer->device->ws->cs_finalize(cmd_buffer->cs)) return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY); + cmd_buffer->status = RADV_CMD_BUFFER_STATUS_EXECUTABLE; + return cmd_buffer->record_result; } @@ -2525,6 +2563,9 @@ radv_emit_compute_pipeline(struct radv_cmd_buffer *cmd_buffer) { struct radv_shader_variant *compute_shader; struct radv_pipeline *pipeline = cmd_buffer->state.compute_pipeline; + struct radv_device *device = cmd_buffer->device; + unsigned compute_resource_limits; + unsigned waves_per_threadgroup; uint64_t va; if (!pipeline || pipeline == cmd_buffer->state.emitted_compute_pipeline) @@ -2536,7 +2577,7 @@ radv_emit_compute_pipeline(struct radv_cmd_buffer *cmd_buffer) va = radv_buffer_get_va(compute_shader->bo) + compute_shader->bo_offset; MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws, - cmd_buffer->cs, 16); + cmd_buffer->cs, 19); radeon_set_sh_reg_seq(cmd_buffer->cs, R_00B830_COMPUTE_PGM_LO, 2); radeon_emit(cmd_buffer->cs, va >> 8); @@ -2556,6 +2597,30 @@ radv_emit_compute_pipeline(struct radv_cmd_buffer *cmd_buffer) S_00B860_WAVES(pipeline->max_waves) | S_00B860_WAVESIZE(pipeline->scratch_bytes_per_wave >> 10)); + /* Calculate best compute resource limits. */ + waves_per_threadgroup = + DIV_ROUND_UP(compute_shader->info.cs.block_size[0] * + compute_shader->info.cs.block_size[1] * + compute_shader->info.cs.block_size[2], 64); + compute_resource_limits = + S_00B854_SIMD_DEST_CNTL(waves_per_threadgroup % 4 == 0); + + if (device->physical_device->rad_info.chip_class >= CIK) { + unsigned num_cu_per_se = + device->physical_device->rad_info.num_good_compute_units / + device->physical_device->rad_info.max_se; + + /* Force even distribution on all SIMDs in CU if the workgroup + * size is 64. This has shown some good improvements if # of + * CUs per SE is not a multiple of 4. + */ + if (num_cu_per_se % 4 && waves_per_threadgroup == 1) + compute_resource_limits |= S_00B854_FORCE_SIMD_DIST(1); + } + + radeon_set_sh_reg(cmd_buffer->cs, R_00B854_COMPUTE_RESOURCE_LIMITS, + compute_resource_limits); + radeon_set_sh_reg_seq(cmd_buffer->cs, R_00B81C_COMPUTE_NUM_THREAD_X, 3); radeon_emit(cmd_buffer->cs, S_00B81C_NUM_THREAD_FULL(compute_shader->info.cs.block_size[0])); @@ -2827,6 +2892,11 @@ void radv_CmdExecuteCommands( primary->state.last_ia_multi_vgt_param = secondary->state.last_ia_multi_vgt_param; } + + if (secondary->state.last_index_type != -1) { + primary->state.last_index_type = + secondary->state.last_index_type; + } } /* After executing commands from secondary buffers we have to dirty @@ -3211,8 +3281,10 @@ radv_emit_all_graphics_states(struct radv_cmd_buffer *cmd_buffer, * so the state must be re-emitted before the next indexed * draw. */ - if (cmd_buffer->device->physical_device->rad_info.chip_class >= CIK) + if (cmd_buffer->device->physical_device->rad_info.chip_class >= CIK) { + cmd_buffer->state.last_index_type = -1; cmd_buffer->state.dirty |= RADV_CMD_DIRTY_INDEX_BUFFER; + } } radv_cmd_buffer_flush_dynamic_state(cmd_buffer); @@ -3440,29 +3512,16 @@ radv_emit_dispatch_packets(struct radv_cmd_buffer *cmd_buffer, { struct radv_pipeline *pipeline = cmd_buffer->state.compute_pipeline; struct radv_shader_variant *compute_shader = pipeline->shaders[MESA_SHADER_COMPUTE]; + unsigned dispatch_initiator = cmd_buffer->device->dispatch_initiator; struct radeon_winsys *ws = cmd_buffer->device->ws; struct radeon_winsys_cs *cs = cmd_buffer->cs; struct ac_userdata_info *loc; - unsigned dispatch_initiator; - uint8_t grid_used; - - grid_used = compute_shader->info.info.cs.grid_components_used; loc = radv_lookup_user_sgpr(pipeline, MESA_SHADER_COMPUTE, AC_UD_CS_GRID_SIZE); MAYBE_UNUSED unsigned cdw_max = radeon_check_space(ws, cs, 25); - dispatch_initiator = S_00B800_COMPUTE_SHADER_EN(1) | - S_00B800_FORCE_START_AT_000(1); - - if (cmd_buffer->device->physical_device->rad_info.chip_class >= CIK) { - /* If the KMD allows it (there is a KMD hw register for it), - * allow launching waves out-of-order. - */ - dispatch_initiator |= S_00B800_ORDER_MODE(1); - } - if (info->indirect) { uint64_t va = radv_buffer_get_va(info->indirect->bo); @@ -3471,7 +3530,7 @@ radv_emit_dispatch_packets(struct radv_cmd_buffer *cmd_buffer, radv_cs_add_buffer(ws, cs, info->indirect->bo, 8); if (loc->sgpr_idx != -1) { - for (unsigned i = 0; i < grid_used; ++i) { + for (unsigned i = 0; i < 3; ++i) { radeon_emit(cs, PKT3(PKT3_COPY_DATA, 4, 0)); radeon_emit(cs, COPY_DATA_SRC_SEL(COPY_DATA_MEM) | COPY_DATA_DST_SEL(COPY_DATA_REG)); @@ -3538,15 +3597,13 @@ radv_emit_dispatch_packets(struct radv_cmd_buffer *cmd_buffer, if (loc->sgpr_idx != -1) { assert(!loc->indirect); - assert(loc->num_sgprs == grid_used); + assert(loc->num_sgprs == 3); radeon_set_sh_reg_seq(cs, R_00B900_COMPUTE_USER_DATA_0 + - loc->sgpr_idx * 4, grid_used); + loc->sgpr_idx * 4, 3); radeon_emit(cs, blocks[0]); - if (grid_used > 1) - radeon_emit(cs, blocks[1]); - if (grid_used > 2) - radeon_emit(cs, blocks[2]); + radeon_emit(cs, blocks[1]); + radeon_emit(cs, blocks[2]); } radeon_emit(cs, PKT3(PKT3_DISPATCH_DIRECT, 3, 0) |