{
struct radv_cmd_buffer *cmd_buffer;
unsigned ring;
- cmd_buffer = vk_alloc(&pool->alloc, sizeof(*cmd_buffer), 8,
- VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
+ cmd_buffer = vk_zalloc(&pool->alloc, sizeof(*cmd_buffer), 8,
+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
if (cmd_buffer == NULL)
return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
- memset(cmd_buffer, 0, sizeof(*cmd_buffer));
cmd_buffer->_loader_data.loaderMagic = ICD_LOADER_MAGIC;
cmd_buffer->device = device;
cmd_buffer->pool = pool;
*pCommandBuffer = radv_cmd_buffer_to_handle(cmd_buffer);
- cmd_buffer->upload.offset = 0;
- cmd_buffer->upload.size = 0;
list_inithead(&cmd_buffer->upload.list);
return VK_SUCCESS;
cmd_buffer->sample_positions_needed = false;
if (cmd_buffer->upload.upload_bo)
- cmd_buffer->device->ws->cs_add_buffer(cmd_buffer->cs,
- cmd_buffer->upload.upload_bo, 8);
+ radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs,
+ cmd_buffer->upload.upload_bo, 8);
cmd_buffer->upload.offset = 0;
cmd_buffer->record_result = VK_SUCCESS;
cmd_buffer->gfx9_fence_bo = cmd_buffer->upload.upload_bo;
}
+ cmd_buffer->status = RADV_CMD_BUFFER_STATUS_INITIAL;
+
return cmd_buffer->record_result;
}
return false;
}
- device->ws->cs_add_buffer(cmd_buffer->cs, bo, 8);
+ radv_cs_add_buffer(device->ws, cmd_buffer->cs, bo, 8);
if (cmd_buffer->upload.upload_bo) {
upload = malloc(sizeof(*upload));
struct radeon_winsys_cs *cs = cmd_buffer->cs;
uint64_t va;
- if (!device->trace_bo)
- return;
-
va = radv_buffer_get_va(device->trace_bo);
if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY)
va += 4;
MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws, cmd_buffer->cs, 7);
++cmd_buffer->state.trace_id;
- device->ws->cs_add_buffer(cs, device->trace_bo, 8);
+ radv_cs_add_buffer(device->ws, cs, device->trace_bo, 8);
radv_emit_write_data_packet(cs, va, 1, &cmd_buffer->state.trace_id);
radeon_emit(cs, PKT3(PKT3_NOP, 0, 0));
radeon_emit(cs, AC_ENCODE_TRACE_POINT(cmd_buffer->state.trace_id));
flags);
}
- radv_cmd_buffer_trace_emit(cmd_buffer);
+ if (unlikely(cmd_buffer->device->trace_bo))
+ radv_cmd_buffer_trace_emit(cmd_buffer);
}
static void
uint32_t data[2];
uint64_t va;
- if (!device->trace_bo)
- return;
-
va = radv_buffer_get_va(device->trace_bo);
switch (ring) {
data[0] = (uintptr_t)pipeline;
data[1] = (uintptr_t)pipeline >> 32;
- device->ws->cs_add_buffer(cs, device->trace_bo, 8);
+ radv_cs_add_buffer(device->ws, cs, device->trace_bo, 8);
radv_emit_write_data_packet(cs, va, 2, data);
}
data[i * 2 + 1] = (uintptr_t)set >> 32;
}
- device->ws->cs_add_buffer(cs, device->trace_bo, 8);
+ radv_cs_add_buffer(device->ws, cs, device->trace_bo, 8);
radv_emit_write_data_packet(cs, va, MAX_SETS * 2, data);
}
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);
raster->pa_su_sc_mode_cntl);
}
+static inline void
+radv_emit_prefetch_TC_L2_async(struct radv_cmd_buffer *cmd_buffer, uint64_t va,
+ unsigned size)
+{
+ if (cmd_buffer->device->physical_device->rad_info.chip_class >= CIK)
+ si_cp_dma_prefetch(cmd_buffer, va, size);
+}
+
+static void
+radv_emit_VBO_descriptors_prefetch(struct radv_cmd_buffer *cmd_buffer)
+{
+ if (cmd_buffer->state.vb_prefetch_dirty) {
+ radv_emit_prefetch_TC_L2_async(cmd_buffer,
+ cmd_buffer->state.vb_va,
+ cmd_buffer->state.vb_size);
+ cmd_buffer->state.vb_prefetch_dirty = false;
+ }
+}
+
static void
radv_emit_shader_prefetch(struct radv_cmd_buffer *cmd_buffer,
struct radv_shader_variant *shader)
va = radv_buffer_get_va(shader->bo) + shader->bo_offset;
- ws->cs_add_buffer(cs, shader->bo, 8);
- if (cmd_buffer->device->physical_device->rad_info.chip_class >= CIK)
- si_cp_dma_prefetch(cmd_buffer, va, shader->code_size);
+ radv_cs_add_buffer(ws, cs, shader->bo, 8);
+ radv_emit_prefetch_TC_L2_async(cmd_buffer, va, shader->code_size);
}
static void
-radv_emit_shaders_prefetch(struct radv_cmd_buffer *cmd_buffer,
- struct radv_pipeline *pipeline)
+radv_emit_prefetch(struct radv_cmd_buffer *cmd_buffer,
+ struct radv_pipeline *pipeline)
{
radv_emit_shader_prefetch(cmd_buffer,
pipeline->shaders[MESA_SHADER_VERTEX]);
+ radv_emit_VBO_descriptors_prefetch(cmd_buffer);
radv_emit_shader_prefetch(cmd_buffer,
pipeline->shaders[MESA_SHADER_TESS_CTRL]);
radv_emit_shader_prefetch(cmd_buffer,
static void
radv_emit_hw_vs(struct radv_cmd_buffer *cmd_buffer,
struct radv_pipeline *pipeline,
- struct radv_shader_variant *shader,
- struct ac_vs_output_info *outinfo)
+ struct radv_shader_variant *shader)
{
uint64_t va = radv_buffer_get_va(shader->bo) + shader->bo_offset;
- unsigned export_count;
- export_count = MAX2(1, outinfo->param_exports);
radeon_set_context_reg(cmd_buffer->cs, R_0286C4_SPI_VS_OUT_CONFIG,
- S_0286C4_VS_EXPORT_COUNT(export_count - 1));
+ pipeline->graphics.vs.spi_vs_out_config);
radeon_set_context_reg(cmd_buffer->cs, R_02870C_SPI_SHADER_POS_FORMAT,
- S_02870C_POS0_EXPORT_FORMAT(V_02870C_SPI_SHADER_4COMP) |
- S_02870C_POS1_EXPORT_FORMAT(outinfo->pos_exports > 1 ?
- V_02870C_SPI_SHADER_4COMP :
- V_02870C_SPI_SHADER_NONE) |
- S_02870C_POS2_EXPORT_FORMAT(outinfo->pos_exports > 2 ?
- V_02870C_SPI_SHADER_4COMP :
- V_02870C_SPI_SHADER_NONE) |
- S_02870C_POS3_EXPORT_FORMAT(outinfo->pos_exports > 3 ?
- V_02870C_SPI_SHADER_4COMP :
- V_02870C_SPI_SHADER_NONE));
-
+ pipeline->graphics.vs.spi_shader_pos_format);
radeon_set_sh_reg_seq(cmd_buffer->cs, R_00B120_SPI_SHADER_PGM_LO_VS, 4);
radeon_emit(cmd_buffer->cs, va >> 8);
radeon_set_context_reg(cmd_buffer->cs, R_02881C_PA_CL_VS_OUT_CNTL,
- pipeline->graphics.pa_cl_vs_out_cntl);
+ pipeline->graphics.vs.pa_cl_vs_out_cntl);
if (cmd_buffer->device->physical_device->rad_info.chip_class <= VI)
radeon_set_context_reg(cmd_buffer->cs, R_028AB4_VGT_REUSE_OFF,
- S_028AB4_REUSE_OFF(outinfo->writes_viewport_index));
+ pipeline->graphics.vs.vgt_reuse_off);
}
static void
radv_emit_hw_es(struct radv_cmd_buffer *cmd_buffer,
- struct radv_shader_variant *shader,
- struct ac_es_output_info *outinfo)
+ struct radv_pipeline *pipeline,
+ struct radv_shader_variant *shader)
{
uint64_t va = radv_buffer_get_va(shader->bo) + shader->bo_offset;
- radeon_set_context_reg(cmd_buffer->cs, R_028AAC_VGT_ESGS_RING_ITEMSIZE,
- outinfo->esgs_itemsize / 4);
radeon_set_sh_reg_seq(cmd_buffer->cs, R_00B320_SPI_SHADER_PGM_LO_ES, 4);
radeon_emit(cmd_buffer->cs, va >> 8);
radeon_emit(cmd_buffer->cs, va >> 40);
if (vs->info.vs.as_ls)
radv_emit_hw_ls(cmd_buffer, vs);
else if (vs->info.vs.as_es)
- radv_emit_hw_es(cmd_buffer, vs, &vs->info.vs.es_info);
+ radv_emit_hw_es(cmd_buffer, pipeline, vs);
else
- radv_emit_hw_vs(cmd_buffer, pipeline, vs, &vs->info.vs.outinfo);
+ radv_emit_hw_vs(cmd_buffer, pipeline, vs);
}
if (tes) {
if (tes->info.tes.as_es)
- radv_emit_hw_es(cmd_buffer, tes, &tes->info.tes.es_info);
+ radv_emit_hw_es(cmd_buffer, pipeline, tes);
else
- radv_emit_hw_vs(cmd_buffer, pipeline, tes, &tes->info.tes.outinfo);
+ radv_emit_hw_vs(cmd_buffer, pipeline, tes);
}
radv_emit_hw_hs(cmd_buffer, tcs);
S_028B90_CNT(MIN2(gs_num_invocations, 127)) |
S_028B90_ENABLE(gs_num_invocations > 0));
+ radeon_set_context_reg(cmd_buffer->cs, R_028AAC_VGT_ESGS_RING_ITEMSIZE,
+ pipeline->graphics.gs.vgt_esgs_ring_itemsize);
+
va = radv_buffer_get_va(gs->bo) + gs->bo_offset;
if (cmd_buffer->device->physical_device->rad_info.chip_class >= GFX9) {
radeon_set_context_reg(cmd_buffer->cs, R_028A44_VGT_GS_ONCHIP_CNTL, pipeline->graphics.gs.vgt_gs_onchip_cntl);
radeon_set_context_reg(cmd_buffer->cs, R_028A94_VGT_GS_MAX_PRIMS_PER_SUBGROUP, pipeline->graphics.gs.vgt_gs_max_prims_per_subgroup);
- radeon_set_context_reg(cmd_buffer->cs, R_028AAC_VGT_ESGS_RING_ITEMSIZE, pipeline->graphics.gs.vgt_esgs_ring_itemsize);
} else {
radeon_set_sh_reg_seq(cmd_buffer->cs, R_00B220_SPI_SHADER_PGM_LO_GS, 4);
radeon_emit(cmd_buffer->cs, va >> 8);
radeon_emit(cmd_buffer->cs, gs->rsrc2);
}
- radv_emit_hw_vs(cmd_buffer, pipeline, pipeline->gs_copy_shader, &pipeline->gs_copy_shader->info.vs.outinfo);
+ radv_emit_hw_vs(cmd_buffer, pipeline, pipeline->gs_copy_shader);
struct ac_userdata_info *loc = radv_lookup_user_sgpr(cmd_buffer->state.pipeline, MESA_SHADER_GEOMETRY,
AC_UD_GS_VS_RING_STRIDE_ENTRIES);
}
radeon_set_context_reg(cmd_buffer->cs, R_028A6C_VGT_GS_OUT_PRIM_TYPE, pipeline->graphics.gs_out);
- radv_save_pipeline(cmd_buffer, pipeline, RING_GFX);
+ if (unlikely(cmd_buffer->device->trace_bo))
+ radv_save_pipeline(cmd_buffer, pipeline, RING_GFX);
cmd_buffer->state.emitted_pipeline = pipeline;
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);
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);
va += image->offset + image->clear_value_offset;
unsigned reg_offset = 0, reg_count = 0;
- if (!image->surface.htile_size || !aspects)
- return;
+ assert(image->surface.htile_size);
if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
++reg_count;
if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT)
++reg_count;
- cmd_buffer->device->ws->cs_add_buffer(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) |
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;
- cmd_buffer->device->ws->cs_add_buffer(cmd_buffer->cs, image->bo, 8);
+ 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));
uint64_t va = radv_buffer_get_va(image->bo);
va += image->offset + image->dcc_pred_offset;
- if (!image->surface.dcc_size)
- return;
-
- cmd_buffer->device->ws->cs_add_buffer(cmd_buffer->cs, image->bo, 8);
+ 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) |
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;
-
- cmd_buffer->device->ws->cs_add_buffer(cmd_buffer->cs, image->bo, 8);
+ 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) |
return;
uint32_t reg = R_028C8C_CB_COLOR0_CLEAR_WORD0 + idx * 0x3c;
- cmd_buffer->device->ws->cs_add_buffer(cmd_buffer->cs, image->bo, 8);
radeon_emit(cmd_buffer->cs, PKT3(PKT3_COPY_DATA, 4, cmd_buffer->state.predicating));
radeon_emit(cmd_buffer->cs, COPY_DATA_SRC_SEL(COPY_DATA_MEM) |
radeon_emit(cmd_buffer->cs, 0);
}
-void
+static void
radv_emit_framebuffer_state(struct radv_cmd_buffer *cmd_buffer)
{
int i;
int idx = subpass->color_attachments[i].attachment;
struct radv_attachment_info *att = &framebuffer->attachments[idx];
- cmd_buffer->device->ws->cs_add_buffer(cmd_buffer->cs, att->attachment->bo, 8);
+ 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);
}
VkImageLayout layout = subpass->depth_stencil_attachment.layout;
struct radv_attachment_info *att = &framebuffer->attachments[idx];
struct radv_image *image = att->attachment->image;
- cmd_buffer->device->ws->cs_add_buffer(cmd_buffer->cs, att->attachment->bo, 8);
+ radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, att->attachment->bo, 8);
MAYBE_UNUSED uint32_t queue_mask = radv_image_queue_family_mask(image,
cmd_buffer->queue_family_index,
cmd_buffer->queue_family_index);
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;
}
cmd_buffer->state.descriptors_dirty = 0;
cmd_buffer->state.push_descriptors_dirty = false;
- if (cmd_buffer->device->trace_bo)
+ if (unlikely(cmd_buffer->device->trace_bo))
radv_save_descriptors(cmd_buffer);
assert(cmd_buffer->cs->cdw <= cdw_max);
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 +
static bool
radv_cmd_buffer_update_vertex_descriptors(struct radv_cmd_buffer *cmd_buffer, bool pipeline_is_dirty)
{
- struct radv_device *device = cmd_buffer->device;
-
- if ((pipeline_is_dirty || cmd_buffer->state.vb_dirty) &&
+ if ((pipeline_is_dirty ||
+ (cmd_buffer->state.dirty & RADV_CMD_DIRTY_VERTEX_BUFFER)) &&
cmd_buffer->state.pipeline->vertex_elements.count &&
radv_get_vertex_shader(cmd_buffer->state.pipeline)->info.info.vs.has_vertex_buffers) {
struct radv_vertex_elements_info *velems = &cmd_buffer->state.pipeline->vertex_elements;
struct radv_buffer *buffer = cmd_buffer->vertex_bindings[vb].buffer;
uint32_t stride = cmd_buffer->state.pipeline->binding_stride[vb];
- device->ws->cs_add_buffer(cmd_buffer->cs, buffer->bo, 8);
va = radv_buffer_get_va(buffer->bo);
offset = cmd_buffer->vertex_bindings[vb].offset + velems->offset[i];
radv_emit_userdata_address(cmd_buffer, cmd_buffer->state.pipeline, MESA_SHADER_VERTEX,
AC_UD_VS_VERTEX_BUFFERS, va);
+
+ cmd_buffer->state.vb_va = va;
+ cmd_buffer->state.vb_size = count * 16;
+ cmd_buffer->state.vb_prefetch_dirty = true;
}
- cmd_buffer->state.vb_dirty = false;
+ cmd_buffer->state.dirty &= ~RADV_CMD_DIRTY_VERTEX_BUFFER;
return true;
}
VkResult result = VK_SUCCESS;
uint32_t i;
- memset(pCommandBuffers, 0,
- sizeof(*pCommandBuffers)*pAllocateInfo->commandBufferCount);
-
for (i = 0; i < pAllocateInfo->commandBufferCount; i++) {
if (!list_empty(&pool->free_cmd_buffers)) {
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;
}
struct radv_device *device = cmd_buffer->device;
if (device->gfx_init) {
uint64_t va = radv_buffer_get_va(device->gfx_init);
- device->ws->cs_add_buffer(cmd_buffer->cs, device->gfx_init, 8);
+ radv_cs_add_buffer(device->ws, cmd_buffer->cs, device->gfx_init, 8);
radeon_emit(cmd_buffer->cs, PKT3(PKT3_INDIRECT_BUFFER_CIK, 2, 0));
radeon_emit(cmd_buffer->cs, va);
radeon_emit(cmd_buffer->cs, va >> 32);
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 */
radv_cmd_buffer_set_subpass(cmd_buffer, subpass, false);
}
- radv_cmd_buffer_trace_emit(cmd_buffer);
+ if (unlikely(cmd_buffer->device->trace_bo))
+ radv_cmd_buffer_trace_emit(cmd_buffer);
+
+ cmd_buffer->status = RADV_CMD_BUFFER_STATUS_RECORDING;
+
return result;
}
vb[idx].buffer = radv_buffer_from_handle(pBuffers[i]);
vb[idx].offset = pOffsets[i];
+
+ radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs,
+ vb[idx].buffer->bo, 8);
}
if (!changed) {
return;
}
- cmd_buffer->state.vb_dirty = true;
+ cmd_buffer->state.dirty |= RADV_CMD_DIRTY_VERTEX_BUFFER;
}
void radv_CmdBindIndexBuffer(
int index_size_shift = cmd_buffer->state.index_type ? 2 : 1;
cmd_buffer->state.max_index_count = (index_buffer->size - offset) >> index_size_shift;
cmd_buffer->state.dirty |= RADV_CMD_DIRTY_INDEX_BUFFER;
- cmd_buffer->device->ws->cs_add_buffer(cmd_buffer->cs, index_buffer->bo, 8);
+ radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs, index_buffer->bo, 8);
}
for (unsigned j = 0; j < set->layout->buffer_count; ++j)
if (set->descriptors[j])
- ws->cs_add_buffer(cmd_buffer->cs, set->descriptors[j], 7);
+ radv_cs_add_buffer(ws, cmd_buffer->cs, set->descriptors[j], 7);
if(set->bo)
- ws->cs_add_buffer(cmd_buffer->cs, set->bo, 8);
+ radv_cs_add_buffer(ws, cmd_buffer->cs, set->bo, 8);
}
void radv_CmdBindDescriptorSets(
vk_free(&cmd_buffer->pool->alloc, cmd_buffer->state.attachments);
if (!cmd_buffer->device->ws->cs_finalize(cmd_buffer->cs))
- return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+ return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
+
+ cmd_buffer->status = RADV_CMD_BUFFER_STATUS_EXECUTABLE;
return cmd_buffer->record_result;
}
{
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)
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);
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]));
S_00B81C_NUM_THREAD_FULL(compute_shader->info.cs.block_size[2]));
assert(cmd_buffer->cs->cdw <= cdw_max);
- radv_save_pipeline(cmd_buffer, pipeline, RING_COMPUTE);
+
+ if (unlikely(cmd_buffer->device->trace_bo))
+ radv_save_pipeline(cmd_buffer, pipeline, RING_COMPUTE);
}
static void radv_mark_descriptor_sets_dirty(struct radv_cmd_buffer *cmd_buffer)
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
va += info->indirect->offset + info->indirect_offset;
- ws->cs_add_buffer(cs, info->indirect->bo, 8);
+ radv_cs_add_buffer(ws, cs, info->indirect->bo, 8);
radeon_emit(cs, PKT3(PKT3_SET_BASE, 2, 0));
radeon_emit(cs, 1);
count_va += info->count_buffer->offset +
info->count_buffer_offset;
- ws->cs_add_buffer(cs, info->count_buffer->bo, 8);
+ radv_cs_add_buffer(ws, cs, info->count_buffer->bo, 8);
}
if (!state->subpass->view_mask) {
* 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);
* important.
*/
if (pipeline_is_dirty) {
- radv_emit_shaders_prefetch(cmd_buffer,
- cmd_buffer->state.pipeline);
+ radv_emit_prefetch(cmd_buffer,
+ cmd_buffer->state.pipeline);
}
} else {
/* If we don't wait for idle, start prefetches first, then set
si_emit_cache_flush(cmd_buffer);
if (pipeline_is_dirty) {
- radv_emit_shaders_prefetch(cmd_buffer,
- cmd_buffer->state.pipeline);
+ radv_emit_prefetch(cmd_buffer,
+ cmd_buffer->state.pipeline);
}
if (!radv_upload_graphics_shader_descriptors(cmd_buffer, pipeline_is_dirty))
{
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);
va += info->indirect->offset + info->indirect_offset;
- ws->cs_add_buffer(cs, info->indirect->bo, 8);
+ 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));
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) |
struct radeon_winsys_cs *cs = cmd_buffer->cs;
uint64_t va = radv_buffer_get_va(event->bo);
- cmd_buffer->device->ws->cs_add_buffer(cs, event->bo, 8);
+ radv_cs_add_buffer(cmd_buffer->device->ws, cs, event->bo, 8);
MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws, cs, 18);
RADV_FROM_HANDLE(radv_event, event, pEvents[i]);
uint64_t va = radv_buffer_get_va(event->bo);
- cmd_buffer->device->ws->cs_add_buffer(cs, event->bo, 8);
+ radv_cs_add_buffer(cmd_buffer->device->ws, cs, event->bo, 8);
MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws, cs, 7);