if (cmd_buffer->upload.upload_bo)
cmd_buffer->device->ws->buffer_destroy(cmd_buffer->upload.upload_bo);
cmd_buffer->device->ws->cs_destroy(cmd_buffer->cs);
+ free(cmd_buffer->push_descriptors.set.mapped_ptr);
vk_free(&cmd_buffer->pool->alloc, cmd_buffer);
}
cmd_buffer->compute_scratch_size_needed = 0;
cmd_buffer->esgs_ring_size_needed = 0;
cmd_buffer->gsvs_ring_size_needed = 0;
+ cmd_buffer->tess_rings_needed = false;
+ cmd_buffer->sample_positions_needed = false;
if (cmd_buffer->upload.upload_bo)
cmd_buffer->device->ws->cs_add_buffer(cmd_buffer->cs,
}
static uint32_t
-shader_stage_to_user_data_0(gl_shader_stage stage, bool has_gs)
+shader_stage_to_user_data_0(gl_shader_stage stage, bool has_gs, bool has_tess)
{
switch (stage) {
case MESA_SHADER_FRAGMENT:
return R_00B030_SPI_SHADER_USER_DATA_PS_0;
case MESA_SHADER_VERTEX:
- return has_gs ? R_00B330_SPI_SHADER_USER_DATA_ES_0 : R_00B130_SPI_SHADER_USER_DATA_VS_0;
+ if (has_tess)
+ return R_00B530_SPI_SHADER_USER_DATA_LS_0;
+ else
+ return has_gs ? R_00B330_SPI_SHADER_USER_DATA_ES_0 : R_00B130_SPI_SHADER_USER_DATA_VS_0;
case MESA_SHADER_GEOMETRY:
return R_00B230_SPI_SHADER_USER_DATA_GS_0;
case MESA_SHADER_COMPUTE:
return R_00B900_COMPUTE_USER_DATA_0;
+ case MESA_SHADER_TESS_CTRL:
+ return R_00B430_SPI_SHADER_USER_DATA_HS_0;
+ case MESA_SHADER_TESS_EVAL:
+ if (has_gs)
+ return R_00B330_SPI_SHADER_USER_DATA_ES_0;
+ else
+ return R_00B130_SPI_SHADER_USER_DATA_VS_0;
default:
unreachable("unknown shader");
}
int idx, uint64_t va)
{
struct ac_userdata_info *loc = radv_lookup_user_sgpr(pipeline, stage, idx);
- uint32_t base_reg = shader_stage_to_user_data_0(stage, radv_pipeline_has_gs(pipeline));
+ uint32_t base_reg = shader_stage_to_user_data_0(stage, radv_pipeline_has_gs(pipeline), radv_pipeline_has_tess(pipeline));
if (loc->sgpr_idx == -1)
return;
assert(loc->num_sgprs == 2);
radv_cayman_emit_msaa_sample_locs(cmd_buffer->cs, num_samples);
- uint32_t samples_offset;
- void *samples_ptr;
- void *src;
- radv_cmd_buffer_upload_alloc(cmd_buffer, num_samples * 4 * 2, 256, &samples_offset,
- &samples_ptr);
- switch (num_samples) {
- case 1:
- src = cmd_buffer->device->sample_locations_1x;
- break;
- case 2:
- src = cmd_buffer->device->sample_locations_2x;
- break;
- case 4:
- src = cmd_buffer->device->sample_locations_4x;
- break;
- case 8:
- src = cmd_buffer->device->sample_locations_8x;
- break;
- case 16:
- src = cmd_buffer->device->sample_locations_16x;
- break;
- default:
- unreachable("unknown number of samples");
- }
- memcpy(samples_ptr, src, num_samples * 4 * 2);
-
- uint64_t va = cmd_buffer->device->ws->buffer_get_va(cmd_buffer->upload.upload_bo);
- va += samples_offset;
+ if (pipeline->shaders[MESA_SHADER_FRAGMENT]->info.info.ps.needs_sample_positions) {
+ uint32_t offset;
+ struct ac_userdata_info *loc = radv_lookup_user_sgpr(pipeline, MESA_SHADER_FRAGMENT, AC_UD_PS_SAMPLE_POS_OFFSET);
+ uint32_t base_reg = shader_stage_to_user_data_0(MESA_SHADER_FRAGMENT, radv_pipeline_has_gs(pipeline), radv_pipeline_has_tess(pipeline));
+ if (loc->sgpr_idx == -1)
+ return;
+ assert(loc->num_sgprs == 1);
+ assert(!loc->indirect);
+ switch (num_samples) {
+ default:
+ offset = 0;
+ break;
+ case 2:
+ offset = 1;
+ break;
+ case 4:
+ offset = 3;
+ break;
+ case 8:
+ offset = 7;
+ break;
+ case 16:
+ offset = 15;
+ break;
+ }
- radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_FRAGMENT,
- AC_UD_PS_SAMPLE_POS, va);
+ radeon_set_sh_reg(cmd_buffer->cs, base_reg + loc->sgpr_idx * 4, offset);
+ cmd_buffer->sample_positions_needed = true;
+ }
}
static void
radeon_emit(cmd_buffer->cs, shader->rsrc2);
}
+static void
+radv_emit_hw_ls(struct radv_cmd_buffer *cmd_buffer,
+ struct radv_shader_variant *shader)
+{
+ struct radeon_winsys *ws = cmd_buffer->device->ws;
+ uint64_t va = ws->buffer_get_va(shader->bo);
+ uint32_t rsrc2 = shader->rsrc2;
+
+ ws->cs_add_buffer(cmd_buffer->cs, shader->bo, 8);
+
+ radeon_set_sh_reg_seq(cmd_buffer->cs, R_00B520_SPI_SHADER_PGM_LO_LS, 2);
+ radeon_emit(cmd_buffer->cs, va >> 8);
+ radeon_emit(cmd_buffer->cs, va >> 40);
+
+ rsrc2 |= S_00B52C_LDS_SIZE(cmd_buffer->state.pipeline->graphics.tess.lds_size);
+ if (cmd_buffer->device->physical_device->rad_info.chip_class == CIK &&
+ cmd_buffer->device->physical_device->rad_info.family != CHIP_HAWAII)
+ radeon_set_sh_reg(cmd_buffer->cs, R_00B52C_SPI_SHADER_PGM_RSRC2_LS, rsrc2);
+
+ radeon_set_sh_reg_seq(cmd_buffer->cs, R_00B528_SPI_SHADER_PGM_RSRC1_LS, 2);
+ radeon_emit(cmd_buffer->cs, shader->rsrc1);
+ radeon_emit(cmd_buffer->cs, rsrc2);
+}
+
+static void
+radv_emit_hw_hs(struct radv_cmd_buffer *cmd_buffer,
+ struct radv_shader_variant *shader)
+{
+ struct radeon_winsys *ws = cmd_buffer->device->ws;
+ uint64_t va = ws->buffer_get_va(shader->bo);
+
+ ws->cs_add_buffer(cmd_buffer->cs, shader->bo, 8);
+
+ radeon_set_sh_reg_seq(cmd_buffer->cs, R_00B420_SPI_SHADER_PGM_LO_HS, 4);
+ radeon_emit(cmd_buffer->cs, va >> 8);
+ radeon_emit(cmd_buffer->cs, va >> 40);
+ radeon_emit(cmd_buffer->cs, shader->rsrc1);
+ radeon_emit(cmd_buffer->cs, shader->rsrc2);
+}
+
static void
radv_emit_vertex_shader(struct radv_cmd_buffer *cmd_buffer,
struct radv_pipeline *pipeline)
vs = pipeline->shaders[MESA_SHADER_VERTEX];
- if (vs->info.vs.as_es)
+ 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);
else
radv_emit_hw_vs(cmd_buffer, pipeline, vs, &vs->info.vs.outinfo);
}
+static void
+radv_emit_tess_shaders(struct radv_cmd_buffer *cmd_buffer,
+ struct radv_pipeline *pipeline)
+{
+ if (!radv_pipeline_has_tess(pipeline))
+ return;
+
+ struct radv_shader_variant *tes, *tcs;
+
+ tcs = pipeline->shaders[MESA_SHADER_TESS_CTRL];
+ tes = pipeline->shaders[MESA_SHADER_TESS_EVAL];
+
+ if (tes->info.tes.as_es)
+ radv_emit_hw_es(cmd_buffer, tes, &tes->info.tes.es_info);
+ else
+ radv_emit_hw_vs(cmd_buffer, pipeline, tes, &tes->info.tes.outinfo);
+
+ radv_emit_hw_hs(cmd_buffer, tcs);
+
+ radeon_set_context_reg(cmd_buffer->cs, R_028B6C_VGT_TF_PARAM,
+ pipeline->graphics.tess.tf_param);
+
+ if (cmd_buffer->device->physical_device->rad_info.chip_class >= CIK)
+ radeon_set_context_reg_idx(cmd_buffer->cs, R_028B58_VGT_LS_HS_CONFIG, 2,
+ pipeline->graphics.tess.ls_hs_config);
+ else
+ radeon_set_context_reg(cmd_buffer->cs, R_028B58_VGT_LS_HS_CONFIG,
+ pipeline->graphics.tess.ls_hs_config);
+
+ struct ac_userdata_info *loc;
+
+ loc = radv_lookup_user_sgpr(pipeline, MESA_SHADER_TESS_CTRL, AC_UD_TCS_OFFCHIP_LAYOUT);
+ if (loc->sgpr_idx != -1) {
+ uint32_t base_reg = shader_stage_to_user_data_0(MESA_SHADER_TESS_CTRL, radv_pipeline_has_gs(pipeline), radv_pipeline_has_tess(pipeline));
+ assert(loc->num_sgprs == 4);
+ assert(!loc->indirect);
+ radeon_set_sh_reg_seq(cmd_buffer->cs, base_reg + loc->sgpr_idx * 4, 4);
+ radeon_emit(cmd_buffer->cs, pipeline->graphics.tess.offchip_layout);
+ radeon_emit(cmd_buffer->cs, pipeline->graphics.tess.tcs_out_offsets);
+ radeon_emit(cmd_buffer->cs, pipeline->graphics.tess.tcs_out_layout |
+ pipeline->graphics.tess.num_tcs_input_cp << 26);
+ radeon_emit(cmd_buffer->cs, pipeline->graphics.tess.tcs_in_layout);
+ }
+
+ loc = radv_lookup_user_sgpr(pipeline, MESA_SHADER_TESS_EVAL, AC_UD_TES_OFFCHIP_LAYOUT);
+ if (loc->sgpr_idx != -1) {
+ uint32_t base_reg = shader_stage_to_user_data_0(MESA_SHADER_TESS_EVAL, radv_pipeline_has_gs(pipeline), radv_pipeline_has_tess(pipeline));
+ assert(loc->num_sgprs == 1);
+ assert(!loc->indirect);
+
+ radeon_set_sh_reg(cmd_buffer->cs, base_reg + loc->sgpr_idx * 4,
+ pipeline->graphics.tess.offchip_layout);
+ }
+
+ loc = radv_lookup_user_sgpr(pipeline, MESA_SHADER_VERTEX, AC_UD_VS_LS_TCS_IN_LAYOUT);
+ if (loc->sgpr_idx != -1) {
+ uint32_t base_reg = shader_stage_to_user_data_0(MESA_SHADER_VERTEX, radv_pipeline_has_gs(pipeline), radv_pipeline_has_tess(pipeline));
+ assert(loc->num_sgprs == 1);
+ assert(!loc->indirect);
+
+ radeon_set_sh_reg(cmd_buffer->cs, base_reg + loc->sgpr_idx * 4,
+ pipeline->graphics.tess.tcs_in_layout);
+ }
+}
+
static void
radv_emit_geometry_shader(struct radv_cmd_buffer *cmd_buffer,
struct radv_pipeline *pipeline)
}
}
+static void polaris_set_vgt_vertex_reuse(struct radv_cmd_buffer *cmd_buffer,
+ struct radv_pipeline *pipeline)
+{
+ uint32_t vtx_reuse_depth = 30;
+ if (cmd_buffer->device->physical_device->rad_info.family < CHIP_POLARIS10)
+ return;
+
+ if (pipeline->shaders[MESA_SHADER_TESS_EVAL]) {
+ if (pipeline->shaders[MESA_SHADER_TESS_EVAL]->info.tes.spacing == TESS_SPACING_FRACTIONAL_ODD)
+ vtx_reuse_depth = 14;
+ }
+ radeon_set_context_reg(cmd_buffer->cs, R_028C58_VGT_VERTEX_REUSE_BLOCK_CNTL,
+ vtx_reuse_depth);
+}
+
static void
radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer,
struct radv_pipeline *pipeline)
radv_emit_graphics_raster_state(cmd_buffer, pipeline);
radv_update_multisample_state(cmd_buffer, pipeline);
radv_emit_vertex_shader(cmd_buffer, pipeline);
+ radv_emit_tess_shaders(cmd_buffer, pipeline);
radv_emit_geometry_shader(cmd_buffer, pipeline);
radv_emit_fragment_shader(cmd_buffer, pipeline);
-
- radeon_set_context_reg(cmd_buffer->cs, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN,
- pipeline->graphics.prim_restart_enable);
+ polaris_set_vgt_vertex_reuse(cmd_buffer, pipeline);
cmd_buffer->scratch_size_needed =
MAX2(cmd_buffer->scratch_size_needed,
radeon_set_context_reg(cmd_buffer->cs, R_0286E8_SPI_TMPRING_SIZE,
S_0286E8_WAVES(pipeline->max_waves) |
S_0286E8_WAVESIZE(pipeline->scratch_bytes_per_wave >> 10));
+
+ if (!cmd_buffer->state.emitted_pipeline ||
+ cmd_buffer->state.emitted_pipeline->graphics.can_use_guardband !=
+ pipeline->graphics.can_use_guardband)
+ cmd_buffer->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_SCISSOR;
cmd_buffer->state.emitted_pipeline = pipeline;
}
{
uint32_t count = cmd_buffer->state.dynamic.scissor.count;
si_write_scissors(cmd_buffer->cs, 0, count,
- cmd_buffer->state.dynamic.scissor.scissors);
+ cmd_buffer->state.dynamic.scissor.scissors,
+ cmd_buffer->state.dynamic.viewport.viewports,
+ cmd_buffer->state.emitted_pipeline->graphics.can_use_guardband);
radeon_set_context_reg(cmd_buffer->cs, R_028A48_PA_SC_MODE_CNTL_0,
cmd_buffer->state.pipeline->graphics.ms.pa_sc_mode_cntl_0 | S_028A48_VPORT_SCISSOR_ENABLE(count ? 1 : 0));
}
gl_shader_stage stage)
{
struct ac_userdata_info *desc_set_loc = &pipeline->shaders[stage]->info.user_sgprs_locs.descriptor_sets[idx];
- uint32_t base_reg = shader_stage_to_user_data_0(stage, radv_pipeline_has_gs(pipeline));
+ uint32_t base_reg = shader_stage_to_user_data_0(stage, radv_pipeline_has_gs(pipeline), radv_pipeline_has_tess(pipeline));
if (desc_set_loc->sgpr_idx == -1)
return;
idx, set->va,
MESA_SHADER_GEOMETRY);
+ if ((stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) && radv_pipeline_has_tess(pipeline))
+ emit_stage_descriptor_set_userdata(cmd_buffer, pipeline,
+ idx, set->va,
+ MESA_SHADER_TESS_CTRL);
+
+ if ((stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) && radv_pipeline_has_tess(pipeline))
+ emit_stage_descriptor_set_userdata(cmd_buffer, pipeline,
+ idx, set->va,
+ MESA_SHADER_TESS_EVAL);
+
if (stages & VK_SHADER_STAGE_COMPUTE_BIT)
emit_stage_descriptor_set_userdata(cmd_buffer, pipeline,
idx, set->va,
MESA_SHADER_COMPUTE);
}
+static void
+radv_flush_push_descriptors(struct radv_cmd_buffer *cmd_buffer)
+{
+ struct radv_descriptor_set *set = &cmd_buffer->push_descriptors.set;
+ uint32_t *ptr = NULL;
+ unsigned bo_offset;
+
+ if (!radv_cmd_buffer_upload_alloc(cmd_buffer, set->size, 32,
+ &bo_offset,
+ (void**) &ptr))
+ return;
+
+ set->va = cmd_buffer->device->ws->buffer_get_va(cmd_buffer->upload.upload_bo);
+ set->va += bo_offset;
+
+ memcpy(ptr, set->mapped_ptr, set->size);
+}
+
static void
radv_flush_descriptors(struct radv_cmd_buffer *cmd_buffer,
struct radv_pipeline *pipeline,
if (!cmd_buffer->state.descriptors_dirty)
return;
+ if (cmd_buffer->state.push_descriptors_dirty)
+ radv_flush_push_descriptors(cmd_buffer);
+
for (i = 0; i < MAX_SETS; i++) {
if (!(cmd_buffer->state.descriptors_dirty & (1 << i)))
continue;
radv_emit_descriptor_set_userdata(cmd_buffer, pipeline, stages, set, i);
}
cmd_buffer->state.descriptors_dirty = 0;
+ cmd_buffer->state.push_descriptors_dirty = false;
}
static void
radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_GEOMETRY,
AC_UD_PUSH_CONSTANTS, va);
+ if ((stages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) && radv_pipeline_has_tess(pipeline))
+ radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_TESS_CTRL,
+ AC_UD_PUSH_CONSTANTS, va);
+
+ if ((stages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) && radv_pipeline_has_tess(pipeline))
+ radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_TESS_EVAL,
+ AC_UD_PUSH_CONSTANTS, va);
+
if (stages & VK_SHADER_STAGE_COMPUTE_BIT)
radv_emit_userdata_address(cmd_buffer, pipeline, MESA_SHADER_COMPUTE,
AC_UD_PUSH_CONSTANTS, va);
cmd_buffer->push_constant_stages &= ~stages;
}
+static void radv_emit_primitive_reset_state(struct radv_cmd_buffer *cmd_buffer,
+ bool indexed_draw)
+{
+ int32_t primitive_reset_en = indexed_draw && cmd_buffer->state.pipeline->graphics.prim_restart_enable;
+
+ if (primitive_reset_en != cmd_buffer->state.last_primitive_reset_en) {
+ cmd_buffer->state.last_primitive_reset_en = primitive_reset_en;
+ radeon_set_context_reg(cmd_buffer->cs, R_028A94_VGT_MULTI_PRIM_IB_RESET_EN,
+ primitive_reset_en);
+ }
+
+ if (primitive_reset_en) {
+ uint32_t primitive_reset_index = cmd_buffer->state.index_type ? 0xffffffffu : 0xffffu;
+
+ if (primitive_reset_index != cmd_buffer->state.last_primitive_reset_index) {
+ cmd_buffer->state.last_primitive_reset_index = primitive_reset_index;
+ radeon_set_context_reg(cmd_buffer->cs, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX,
+ primitive_reset_index);
+ }
+ }
+}
+
static void
radv_cmd_buffer_flush_state(struct radv_cmd_buffer *cmd_buffer,
- bool instanced_draw, bool indirect_draw,
+ bool indexed_draw, bool instanced_draw,
+ bool indirect_draw,
uint32_t draw_vertex_count)
{
struct radv_pipeline *pipeline = cmd_buffer->state.pipeline;
struct radv_device *device = cmd_buffer->device;
uint32_t ia_multi_vgt_param;
- uint32_t ls_hs_config = 0;
MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws,
cmd_buffer->cs, 4096);
if (cmd_buffer->state.dirty & (RADV_CMD_DIRTY_DYNAMIC_VIEWPORT))
radv_emit_viewport(cmd_buffer);
- if (cmd_buffer->state.dirty & (RADV_CMD_DIRTY_DYNAMIC_SCISSOR))
+ if (cmd_buffer->state.dirty & (RADV_CMD_DIRTY_DYNAMIC_SCISSOR | RADV_CMD_DIRTY_DYNAMIC_VIEWPORT))
radv_emit_scissor(cmd_buffer);
ia_multi_vgt_param = si_get_ia_multi_vgt_param(cmd_buffer, instanced_draw, indirect_draw, draw_vertex_count);
radeon_set_context_reg(cmd_buffer->cs, R_028B54_VGT_SHADER_STAGES_EN, pipeline->graphics.vgt_shader_stages_en);
if (cmd_buffer->device->physical_device->rad_info.chip_class >= CIK) {
- radeon_set_context_reg_idx(cmd_buffer->cs, R_028B58_VGT_LS_HS_CONFIG, 2, ls_hs_config);
radeon_set_uconfig_reg_idx(cmd_buffer->cs, R_030908_VGT_PRIMITIVE_TYPE, 1, cmd_buffer->state.pipeline->graphics.prim);
} else {
radeon_set_config_reg(cmd_buffer->cs, R_008958_VGT_PRIMITIVE_TYPE, cmd_buffer->state.pipeline->graphics.prim);
- radeon_set_context_reg(cmd_buffer->cs, R_028B58_VGT_LS_HS_CONFIG, ls_hs_config);
}
radeon_set_context_reg(cmd_buffer->cs, R_028A6C_VGT_GS_OUT_PRIM_TYPE, cmd_buffer->state.pipeline->graphics.gs_out);
}
radv_cmd_buffer_flush_dynamic_state(cmd_buffer);
+ radv_emit_primitive_reset_state(cmd_buffer, indexed_draw);
+
radv_flush_descriptors(cmd_buffer, cmd_buffer->state.pipeline,
VK_SHADER_STAGE_ALL_GRAPHICS);
radv_flush_constants(cmd_buffer, cmd_buffer->state.pipeline,
radv_reset_cmd_buffer(cmd_buffer);
memset(&cmd_buffer->state, 0, sizeof(cmd_buffer->state));
+ cmd_buffer->state.last_primitive_reset_en = -1;
/* setup initial configuration into command buffer */
if (cmd_buffer->level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) {
radv_cmd_buffer_set_subpass(cmd_buffer, subpass, false);
}
+ radv_cmd_buffer_trace_emit(cmd_buffer);
return VK_SUCCESS;
}
RADV_FROM_HANDLE(radv_pipeline_layout, layout, _layout);
unsigned dyn_idx = 0;
- MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws,
- cmd_buffer->cs, MAX_SETS * 4 * 6);
-
for (unsigned i = 0; i < descriptorSetCount; ++i) {
unsigned idx = i + firstSet;
RADV_FROM_HANDLE(radv_descriptor_set, set, pDescriptorSets[i]);
set->layout->dynamic_shader_stages;
}
}
+}
- assert(cmd_buffer->cs->cdw <= cdw_max);
+static bool radv_init_push_descriptor_set(struct radv_cmd_buffer *cmd_buffer,
+ struct radv_descriptor_set *set,
+ struct radv_descriptor_set_layout *layout)
+{
+ set->size = layout->size;
+ set->layout = layout;
+
+ if (cmd_buffer->push_descriptors.capacity < set->size) {
+ size_t new_size = MAX2(set->size, 1024);
+ new_size = MAX2(new_size, 2 * cmd_buffer->push_descriptors.capacity);
+ new_size = MIN2(new_size, 96 * MAX_PUSH_DESCRIPTORS);
+
+ free(set->mapped_ptr);
+ set->mapped_ptr = malloc(new_size);
+
+ if (!set->mapped_ptr) {
+ cmd_buffer->push_descriptors.capacity = 0;
+ cmd_buffer->record_fail = true;
+ return false;
+ }
+
+ cmd_buffer->push_descriptors.capacity = new_size;
+ }
+
+ return true;
+}
+
+void radv_meta_push_descriptor_set(
+ struct radv_cmd_buffer* cmd_buffer,
+ VkPipelineBindPoint pipelineBindPoint,
+ VkPipelineLayout _layout,
+ uint32_t set,
+ uint32_t descriptorWriteCount,
+ const VkWriteDescriptorSet* pDescriptorWrites)
+{
+ RADV_FROM_HANDLE(radv_pipeline_layout, layout, _layout);
+ struct radv_descriptor_set *push_set = &cmd_buffer->meta_push_descriptors;
+ unsigned bo_offset;
+
+ assert(layout->set[set].layout->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
+
+ push_set->size = layout->set[set].layout->size;
+ push_set->layout = layout->set[set].layout;
+
+ if (!radv_cmd_buffer_upload_alloc(cmd_buffer, push_set->size, 32,
+ &bo_offset,
+ (void**) &push_set->mapped_ptr))
+ return;
+
+ push_set->va = cmd_buffer->device->ws->buffer_get_va(cmd_buffer->upload.upload_bo);
+ push_set->va += bo_offset;
+
+ radv_update_descriptor_sets(cmd_buffer->device, cmd_buffer,
+ radv_descriptor_set_to_handle(push_set),
+ descriptorWriteCount, pDescriptorWrites, 0, NULL);
+
+ cmd_buffer->state.descriptors[set] = push_set;
+ cmd_buffer->state.descriptors_dirty |= (1 << set);
+}
+
+void radv_CmdPushDescriptorSetKHR(
+ VkCommandBuffer commandBuffer,
+ VkPipelineBindPoint pipelineBindPoint,
+ VkPipelineLayout _layout,
+ uint32_t set,
+ uint32_t descriptorWriteCount,
+ const VkWriteDescriptorSet* pDescriptorWrites)
+{
+ RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+ RADV_FROM_HANDLE(radv_pipeline_layout, layout, _layout);
+ struct radv_descriptor_set *push_set = &cmd_buffer->push_descriptors.set;
+
+ assert(layout->set[set].layout->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
+
+ if (!radv_init_push_descriptor_set(cmd_buffer, push_set, layout->set[set].layout))
+ return;
+
+ radv_update_descriptor_sets(cmd_buffer->device, cmd_buffer,
+ radv_descriptor_set_to_handle(push_set),
+ descriptorWriteCount, pDescriptorWrites, 0, NULL);
+
+ cmd_buffer->state.descriptors[set] = push_set;
+ cmd_buffer->state.descriptors_dirty |= (1 << set);
+ cmd_buffer->state.push_descriptors_dirty = true;
+}
+
+void radv_CmdPushDescriptorSetWithTemplateKHR(
+ VkCommandBuffer commandBuffer,
+ VkDescriptorUpdateTemplateKHR descriptorUpdateTemplate,
+ VkPipelineLayout _layout,
+ uint32_t set,
+ const void* pData)
+{
+ RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
+ RADV_FROM_HANDLE(radv_pipeline_layout, layout, _layout);
+ struct radv_descriptor_set *push_set = &cmd_buffer->push_descriptors.set;
+
+ assert(layout->set[set].layout->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR);
+
+ if (!radv_init_push_descriptor_set(cmd_buffer, push_set, layout->set[set].layout))
+ return;
+
+ radv_update_descriptor_set_with_template(cmd_buffer->device, cmd_buffer, push_set,
+ descriptorUpdateTemplate, pData);
+
+ cmd_buffer->state.descriptors[set] = push_set;
+ cmd_buffer->state.descriptors_dirty |= (1 << set);
+ cmd_buffer->state.push_descriptors_dirty = true;
}
void radv_CmdPushConstants(VkCommandBuffer commandBuffer,
if (pipeline->graphics.gsvs_ring_size > cmd_buffer->gsvs_ring_size_needed)
cmd_buffer->gsvs_ring_size_needed = pipeline->graphics.gsvs_ring_size;
+ if (radv_pipeline_has_tess(pipeline))
+ cmd_buffer->tess_rings_needed = true;
+
if (radv_pipeline_has_gs(pipeline)) {
struct ac_userdata_info *loc = radv_lookup_user_sgpr(cmd_buffer->state.pipeline, MESA_SHADER_GEOMETRY,
AC_UD_SCRATCH_RING_OFFSETS);
primary->esgs_ring_size_needed = secondary->esgs_ring_size_needed;
if (secondary->gsvs_ring_size_needed > primary->gsvs_ring_size_needed)
primary->gsvs_ring_size_needed = secondary->gsvs_ring_size_needed;
+ if (secondary->tess_rings_needed)
+ primary->tess_rings_needed = true;
+ if (secondary->sample_positions_needed)
+ primary->sample_positions_needed = true;
if (secondary->ring_offsets_idx != -1) {
if (primary->ring_offsets_idx == -1)
primary->state.emitted_compute_pipeline = NULL;
primary->state.dirty |= RADV_CMD_DIRTY_PIPELINE;
primary->state.dirty |= RADV_CMD_DIRTY_DYNAMIC_ALL;
+ primary->state.last_primitive_reset_en = -1;
+ primary->state.last_primitive_reset_index = 0;
}
}
{
RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
- radv_cmd_buffer_flush_state(cmd_buffer, (instanceCount > 1), false, vertexCount);
+ radv_cmd_buffer_flush_state(cmd_buffer, false, (instanceCount > 1), false, vertexCount);
MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws, cmd_buffer->cs, 10);
struct ac_userdata_info *loc = radv_lookup_user_sgpr(cmd_buffer->state.pipeline, MESA_SHADER_VERTEX,
AC_UD_VS_BASE_VERTEX_START_INSTANCE);
if (loc->sgpr_idx != -1) {
- uint32_t base_reg = shader_stage_to_user_data_0(MESA_SHADER_VERTEX, radv_pipeline_has_gs(cmd_buffer->state.pipeline));
+ uint32_t base_reg = shader_stage_to_user_data_0(MESA_SHADER_VERTEX, radv_pipeline_has_gs(cmd_buffer->state.pipeline),
+ radv_pipeline_has_tess(cmd_buffer->state.pipeline));
radeon_set_sh_reg_seq(cmd_buffer->cs, base_reg + loc->sgpr_idx * 4, 3);
radeon_emit(cmd_buffer->cs, firstVertex);
radeon_emit(cmd_buffer->cs, firstInstance);
radv_cmd_buffer_trace_emit(cmd_buffer);
}
-static void radv_emit_primitive_reset_index(struct radv_cmd_buffer *cmd_buffer)
-{
- uint32_t primitive_reset_index = cmd_buffer->state.index_type ? 0xffffffffu : 0xffffu;
-
- if (cmd_buffer->state.pipeline->graphics.prim_restart_enable &&
- primitive_reset_index != cmd_buffer->state.last_primitive_reset_index) {
- cmd_buffer->state.last_primitive_reset_index = primitive_reset_index;
- radeon_set_context_reg(cmd_buffer->cs, R_02840C_VGT_MULTI_PRIM_IB_RESET_INDX,
- primitive_reset_index);
- }
-}
-
void radv_CmdDrawIndexed(
VkCommandBuffer commandBuffer,
uint32_t indexCount,
uint32_t index_max_size = (cmd_buffer->state.index_buffer->size - cmd_buffer->state.index_offset) / index_size;
uint64_t index_va;
- radv_cmd_buffer_flush_state(cmd_buffer, (instanceCount > 1), false, indexCount);
- radv_emit_primitive_reset_index(cmd_buffer);
+ radv_cmd_buffer_flush_state(cmd_buffer, true, (instanceCount > 1), false, indexCount);
MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws, cmd_buffer->cs, 15);
struct ac_userdata_info *loc = radv_lookup_user_sgpr(cmd_buffer->state.pipeline, MESA_SHADER_VERTEX,
AC_UD_VS_BASE_VERTEX_START_INSTANCE);
if (loc->sgpr_idx != -1) {
- uint32_t base_reg = shader_stage_to_user_data_0(MESA_SHADER_VERTEX, radv_pipeline_has_gs(cmd_buffer->state.pipeline));
+ uint32_t base_reg = shader_stage_to_user_data_0(MESA_SHADER_VERTEX, radv_pipeline_has_gs(cmd_buffer->state.pipeline),
+ radv_pipeline_has_tess(cmd_buffer->state.pipeline));
radeon_set_sh_reg_seq(cmd_buffer->cs, base_reg + loc->sgpr_idx * 4, 3);
radeon_emit(cmd_buffer->cs, vertexOffset);
radeon_emit(cmd_buffer->cs, firstInstance);
struct ac_userdata_info *loc = radv_lookup_user_sgpr(cmd_buffer->state.pipeline, MESA_SHADER_VERTEX,
AC_UD_VS_BASE_VERTEX_START_INSTANCE);
- uint32_t base_reg = shader_stage_to_user_data_0(MESA_SHADER_VERTEX, radv_pipeline_has_gs(cmd_buffer->state.pipeline));
+ uint32_t base_reg = shader_stage_to_user_data_0(MESA_SHADER_VERTEX, radv_pipeline_has_gs(cmd_buffer->state.pipeline),
+ radv_pipeline_has_tess(cmd_buffer->state.pipeline));
assert(loc->sgpr_idx != -1);
radeon_emit(cs, PKT3(PKT3_SET_BASE, 2, 0));
radeon_emit(cs, 1);
uint32_t stride)
{
RADV_FROM_HANDLE(radv_cmd_buffer, cmd_buffer, commandBuffer);
- radv_cmd_buffer_flush_state(cmd_buffer, false, true, 0);
+ radv_cmd_buffer_flush_state(cmd_buffer, false, false, true, 0);
MAYBE_UNUSED unsigned cdw_max = radeon_check_space(cmd_buffer->device->ws,
cmd_buffer->cs, 14);
int index_size = cmd_buffer->state.index_type ? 4 : 2;
uint32_t index_max_size = (cmd_buffer->state.index_buffer->size - cmd_buffer->state.index_offset) / index_size;
uint64_t index_va;
- radv_cmd_buffer_flush_state(cmd_buffer, false, true, 0);
- radv_emit_primitive_reset_index(cmd_buffer);
+ radv_cmd_buffer_flush_state(cmd_buffer, true, false, true, 0);
index_va = cmd_buffer->device->ws->buffer_get_va(cmd_buffer->state.index_buffer->bo);
index_va += cmd_buffer->state.index_buffer->offset + cmd_buffer->state.index_offset;