cmd_buffer->queue_family_index = pool->queue_family_index;
} else {
- /* Init the pool_link so we can safefly call list_del when we destroy
+ /* Init the pool_link so we can safely call list_del when we destroy
* the command buffer
*/
list_inithead(&cmd_buffer->pool_link);
new_size, 4096,
RADEON_DOMAIN_GTT,
RADEON_FLAG_CPU_ACCESS|
- RADEON_FLAG_NO_INTERPROCESS_SHARING);
+ RADEON_FLAG_NO_INTERPROCESS_SHARING |
+ RADEON_FLAG_32BIT);
if (!bo) {
cmd_buffer->record_result = VK_ERROR_OUT_OF_DEVICE_MEMORY;
uint32_t base_reg = pipeline->user_data_0[stage];
if (loc->sgpr_idx == -1)
return;
- assert(loc->num_sgprs == 2);
+
+ assert(loc->num_sgprs == (HAVE_32BIT_POINTERS ? 1 : 2));
assert(!loc->indirect);
- radeon_set_sh_reg_seq(cmd_buffer->cs, base_reg + loc->sgpr_idx * 4, 2);
- radeon_emit(cmd_buffer->cs, va);
- radeon_emit(cmd_buffer->cs, va >> 32);
+
+ radv_emit_shader_pointer(cmd_buffer->device, cmd_buffer->cs,
+ base_reg + loc->sgpr_idx * 4, va, false);
}
static void
radv_emit_shader_prefetch(struct radv_cmd_buffer *cmd_buffer,
struct radv_shader_variant *shader)
{
- struct radeon_winsys *ws = cmd_buffer->device->ws;
- struct radeon_winsys_cs *cs = cmd_buffer->cs;
uint64_t va;
if (!shader)
va = radv_buffer_get_va(shader->bo) + shader->bo_offset;
- radv_cs_add_buffer(ws, cs, shader->bo, 8);
si_cp_dma_prefetch(cmd_buffer, va, shader->code_size);
}
state->prefetch_L2_mask &= ~mask;
}
+static void
+radv_emit_rbplus_state(struct radv_cmd_buffer *cmd_buffer)
+{
+ if (!cmd_buffer->device->physical_device->rbplus_allowed)
+ return;
+
+ struct radv_pipeline *pipeline = cmd_buffer->state.pipeline;
+ struct radv_framebuffer *framebuffer = cmd_buffer->state.framebuffer;
+ const struct radv_subpass *subpass = cmd_buffer->state.subpass;
+
+ unsigned sx_ps_downconvert = 0;
+ unsigned sx_blend_opt_epsilon = 0;
+ unsigned sx_blend_opt_control = 0;
+
+ for (unsigned i = 0; i < subpass->color_count; ++i) {
+ if (subpass->color_attachments[i].attachment == VK_ATTACHMENT_UNUSED)
+ continue;
+
+ int idx = subpass->color_attachments[i].attachment;
+ struct radv_color_buffer_info *cb = &framebuffer->attachments[idx].cb;
+
+ unsigned format = G_028C70_FORMAT(cb->cb_color_info);
+ unsigned swap = G_028C70_COMP_SWAP(cb->cb_color_info);
+ uint32_t spi_format = (pipeline->graphics.col_format >> (i * 4)) & 0xf;
+ uint32_t colormask = (pipeline->graphics.cb_target_mask >> (i * 4)) & 0xf;
+
+ bool has_alpha, has_rgb;
+
+ /* Set if RGB and A are present. */
+ has_alpha = !G_028C74_FORCE_DST_ALPHA_1(cb->cb_color_attrib);
+
+ if (format == V_028C70_COLOR_8 ||
+ format == V_028C70_COLOR_16 ||
+ format == V_028C70_COLOR_32)
+ has_rgb = !has_alpha;
+ else
+ has_rgb = true;
+
+ /* Check the colormask and export format. */
+ if (!(colormask & 0x7))
+ has_rgb = false;
+ if (!(colormask & 0x8))
+ has_alpha = false;
+
+ if (spi_format == V_028714_SPI_SHADER_ZERO) {
+ has_rgb = false;
+ has_alpha = false;
+ }
+
+ /* Disable value checking for disabled channels. */
+ if (!has_rgb)
+ sx_blend_opt_control |= S_02875C_MRT0_COLOR_OPT_DISABLE(1) << (i * 4);
+ if (!has_alpha)
+ sx_blend_opt_control |= S_02875C_MRT0_ALPHA_OPT_DISABLE(1) << (i * 4);
+
+ /* Enable down-conversion for 32bpp and smaller formats. */
+ switch (format) {
+ case V_028C70_COLOR_8:
+ case V_028C70_COLOR_8_8:
+ case V_028C70_COLOR_8_8_8_8:
+ /* For 1 and 2-channel formats, use the superset thereof. */
+ if (spi_format == V_028714_SPI_SHADER_FP16_ABGR ||
+ spi_format == V_028714_SPI_SHADER_UINT16_ABGR ||
+ spi_format == V_028714_SPI_SHADER_SINT16_ABGR) {
+ sx_ps_downconvert |= V_028754_SX_RT_EXPORT_8_8_8_8 << (i * 4);
+ sx_blend_opt_epsilon |= V_028758_8BIT_FORMAT << (i * 4);
+ }
+ break;
+
+ case V_028C70_COLOR_5_6_5:
+ if (spi_format == V_028714_SPI_SHADER_FP16_ABGR) {
+ sx_ps_downconvert |= V_028754_SX_RT_EXPORT_5_6_5 << (i * 4);
+ sx_blend_opt_epsilon |= V_028758_6BIT_FORMAT << (i * 4);
+ }
+ break;
+
+ case V_028C70_COLOR_1_5_5_5:
+ if (spi_format == V_028714_SPI_SHADER_FP16_ABGR) {
+ sx_ps_downconvert |= V_028754_SX_RT_EXPORT_1_5_5_5 << (i * 4);
+ sx_blend_opt_epsilon |= V_028758_5BIT_FORMAT << (i * 4);
+ }
+ break;
+
+ case V_028C70_COLOR_4_4_4_4:
+ if (spi_format == V_028714_SPI_SHADER_FP16_ABGR) {
+ sx_ps_downconvert |= V_028754_SX_RT_EXPORT_4_4_4_4 << (i * 4);
+ sx_blend_opt_epsilon |= V_028758_4BIT_FORMAT << (i * 4);
+ }
+ break;
+
+ case V_028C70_COLOR_32:
+ if (swap == V_028C70_SWAP_STD &&
+ spi_format == V_028714_SPI_SHADER_32_R)
+ sx_ps_downconvert |= V_028754_SX_RT_EXPORT_32_R << (i * 4);
+ else if (swap == V_028C70_SWAP_ALT_REV &&
+ spi_format == V_028714_SPI_SHADER_32_AR)
+ sx_ps_downconvert |= V_028754_SX_RT_EXPORT_32_A << (i * 4);
+ break;
+
+ case V_028C70_COLOR_16:
+ case V_028C70_COLOR_16_16:
+ /* For 1-channel formats, use the superset thereof. */
+ if (spi_format == V_028714_SPI_SHADER_UNORM16_ABGR ||
+ spi_format == V_028714_SPI_SHADER_SNORM16_ABGR ||
+ spi_format == V_028714_SPI_SHADER_UINT16_ABGR ||
+ spi_format == V_028714_SPI_SHADER_SINT16_ABGR) {
+ if (swap == V_028C70_SWAP_STD ||
+ swap == V_028C70_SWAP_STD_REV)
+ sx_ps_downconvert |= V_028754_SX_RT_EXPORT_16_16_GR << (i * 4);
+ else
+ sx_ps_downconvert |= V_028754_SX_RT_EXPORT_16_16_AR << (i * 4);
+ }
+ break;
+
+ case V_028C70_COLOR_10_11_11:
+ if (spi_format == V_028714_SPI_SHADER_FP16_ABGR) {
+ sx_ps_downconvert |= V_028754_SX_RT_EXPORT_10_11_11 << (i * 4);
+ sx_blend_opt_epsilon |= V_028758_11BIT_FORMAT << (i * 4);
+ }
+ break;
+
+ case V_028C70_COLOR_2_10_10_10:
+ if (spi_format == V_028714_SPI_SHADER_FP16_ABGR) {
+ sx_ps_downconvert |= V_028754_SX_RT_EXPORT_2_10_10_10 << (i * 4);
+ sx_blend_opt_epsilon |= V_028758_10BIT_FORMAT << (i * 4);
+ }
+ break;
+ }
+ }
+
+ radeon_set_context_reg_seq(cmd_buffer->cs, R_028754_SX_PS_DOWNCONVERT, 3);
+ radeon_emit(cmd_buffer->cs, sx_ps_downconvert);
+ radeon_emit(cmd_buffer->cs, sx_blend_opt_epsilon);
+ radeon_emit(cmd_buffer->cs, sx_blend_opt_control);
+}
+
static void
radv_emit_graphics_pipeline(struct radv_cmd_buffer *cmd_buffer)
{
radeon_emit_array(cmd_buffer->cs, pipeline->cs.buf, pipeline->cs.cdw);
+ for (unsigned i = 0; i < MESA_SHADER_COMPUTE; i++) {
+ if (!pipeline->shaders[i])
+ continue;
+
+ radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs,
+ pipeline->shaders[i]->bo, 8);
+ }
+
+ if (radv_pipeline_has_gs(pipeline))
+ radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs,
+ pipeline->gs_copy_shader->bo, 8);
+
if (unlikely(cmd_buffer->device->trace_bo))
radv_save_pipeline(cmd_buffer, pipeline, RING_GFX);
}
/*
- *with DCC some colors don't require CMASK elimiation before being
+ * With DCC some colors don't require CMASK elimination before being
* used as a texture. This sets a predicate value to determine if the
* cmask eliminate is required.
*/
void radv_set_db_count_control(struct radv_cmd_buffer *cmd_buffer)
{
+ bool has_perfect_queries = cmd_buffer->state.perfect_occlusion_queries_enabled;
struct radv_pipeline *pipeline = cmd_buffer->state.pipeline;
uint32_t pa_sc_mode_cntl_1 =
pipeline ? pipeline->graphics.ms.pa_sc_mode_cntl_1 : 0;
if(!cmd_buffer->state.active_occlusion_queries) {
if (cmd_buffer->device->physical_device->rad_info.chip_class >= CIK) {
if (G_028A4C_OUT_OF_ORDER_PRIMITIVE_ENABLE(pa_sc_mode_cntl_1) &&
- pipeline->graphics.disable_out_of_order_rast_for_occlusion) {
+ pipeline->graphics.disable_out_of_order_rast_for_occlusion &&
+ has_perfect_queries) {
/* Re-enable out-of-order rasterization if the
* bound pipeline supports it and if it's has
- * been disabled before starting occlusion
- * queries.
+ * been disabled before starting any perfect
+ * occlusion queries.
*/
radeon_set_context_reg(cmd_buffer->cs,
R_028A4C_PA_SC_MODE_CNTL_1,
} else {
const struct radv_subpass *subpass = cmd_buffer->state.subpass;
uint32_t sample_rate = subpass ? util_logbase2(subpass->max_sample_count) : 0;
- bool perfect = cmd_buffer->state.perfect_occlusion_queries_enabled;
if (cmd_buffer->device->physical_device->rad_info.chip_class >= CIK) {
db_count_control =
- S_028004_PERFECT_ZPASS_COUNTS(perfect) |
+ S_028004_PERFECT_ZPASS_COUNTS(has_perfect_queries) |
S_028004_SAMPLE_RATE(sample_rate) |
S_028004_ZPASS_ENABLE(1) |
S_028004_SLICE_EVEN_ENABLE(1) |
S_028004_SLICE_ODD_ENABLE(1);
if (G_028A4C_OUT_OF_ORDER_PRIMITIVE_ENABLE(pa_sc_mode_cntl_1) &&
- pipeline->graphics.disable_out_of_order_rast_for_occlusion) {
+ pipeline->graphics.disable_out_of_order_rast_for_occlusion &&
+ has_perfect_queries) {
/* If the bound pipeline has enabled
* out-of-order rasterization, we should
- * disable it before starting occlusion
- * queries.
+ * disable it before starting any perfect
+ * occlusion queries.
*/
pa_sc_mode_cntl_1 &= C_028A4C_OUT_OF_ORDER_PRIMITIVE_ENABLE;
return;
assert(!desc_set_loc->indirect);
- assert(desc_set_loc->num_sgprs == 2);
- radeon_set_sh_reg_seq(cmd_buffer->cs,
- base_reg + desc_set_loc->sgpr_idx * 4, 2);
- radeon_emit(cmd_buffer->cs, va);
- radeon_emit(cmd_buffer->cs, va >> 32);
+ assert(desc_set_loc->num_sgprs == (HAVE_32BIT_POINTERS ? 1 : 2));
+
+ radv_emit_shader_pointer(cmd_buffer->device, cmd_buffer->cs,
+ base_reg + desc_set_loc->sgpr_idx * 4, va, false);
}
static void
assert(!(set->layout->flags & VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR));
- for (unsigned j = 0; j < set->layout->buffer_count; ++j)
- if (set->descriptors[j])
- radv_cs_add_buffer(ws, cmd_buffer->cs, set->descriptors[j], 7);
+ if (!cmd_buffer->device->use_global_bo_list) {
+ for (unsigned j = 0; j < set->layout->buffer_count; ++j)
+ if (set->descriptors[j])
+ radv_cs_add_buffer(ws, cmd_buffer->cs, set->descriptors[j], 7);
+ }
if(set->bo)
radv_cs_add_buffer(ws, cmd_buffer->cs, set->bo, 8);
RADV_FROM_HANDLE(radv_pipeline_layout, layout, _layout);
unsigned dyn_idx = 0;
+ const bool no_dynamic_bounds = cmd_buffer->device->instance->debug_flags & RADV_DEBUG_NO_DYNAMIC_BOUNDS;
+
for (unsigned i = 0; i < descriptorSetCount; ++i) {
unsigned idx = i + firstSet;
RADV_FROM_HANDLE(radv_descriptor_set, set, pDescriptorSets[i]);
uint64_t va = range->va + pDynamicOffsets[dyn_idx];
dst[0] = va;
dst[1] = S_008F04_BASE_ADDRESS_HI(va >> 32);
- dst[2] = range->size;
+ dst[2] = no_dynamic_bounds ? 0xffffffffu : range->size;
dst[3] = S_008F0C_DST_SEL_X(V_008F0C_SQ_SEL_X) |
S_008F0C_DST_SEL_Y(V_008F0C_SQ_SEL_Y) |
S_008F0C_DST_SEL_Z(V_008F0C_SQ_SEL_Z) |
MAX2(cmd_buffer->compute_scratch_size_needed,
pipeline->max_waves * pipeline->scratch_bytes_per_wave);
+ radv_cs_add_buffer(cmd_buffer->device->ws, cmd_buffer->cs,
+ pipeline->shaders[MESA_SHADER_COMPUTE]->bo, 8);
+
if (unlikely(cmd_buffer->device->trace_bo))
radv_save_pipeline(cmd_buffer, pipeline, RING_COMPUTE);
}
radv_emit_all_graphics_states(struct radv_cmd_buffer *cmd_buffer,
const struct radv_draw_info *info)
{
+ if ((cmd_buffer->state.dirty & RADV_CMD_DIRTY_FRAMEBUFFER) ||
+ cmd_buffer->state.emitted_pipeline != cmd_buffer->state.pipeline)
+ radv_emit_rbplus_state(cmd_buffer);
+
if (cmd_buffer->state.dirty & RADV_CMD_DIRTY_PIPELINE)
radv_emit_graphics_pipeline(cmd_buffer);
const VkImageSubresourceRange *range,
VkImageAspectFlags pending_clears)
{
+ if (!radv_image_has_htile(image))
+ return;
+
if (dst_layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL &&
(pending_clears & vk_format_aspects(image->vk_format)) == vk_format_aspects(image->vk_format) &&
cmd_buffer->state.render_area.offset.x == 0 && cmd_buffer->state.render_area.offset.y == 0 &&
}
}
-void radv_initialise_cmask(struct radv_cmd_buffer *cmd_buffer,
- struct radv_image *image, uint32_t value)
+static void radv_initialise_cmask(struct radv_cmd_buffer *cmd_buffer,
+ struct radv_image *image, uint32_t value)
{
struct radv_cmd_state *state = &cmd_buffer->state;
state->flush_bits |= RADV_CMD_FLAG_FLUSH_AND_INV_CB_META;
}
-static void radv_handle_cmask_image_transition(struct radv_cmd_buffer *cmd_buffer,
- struct radv_image *image,
- VkImageLayout src_layout,
- VkImageLayout dst_layout,
- unsigned src_queue_mask,
- unsigned dst_queue_mask,
- const VkImageSubresourceRange *range)
-{
- if (src_layout == VK_IMAGE_LAYOUT_UNDEFINED) {
- if (radv_image_has_fmask(image))
- radv_initialise_cmask(cmd_buffer, image, 0xccccccccu);
- else
- radv_initialise_cmask(cmd_buffer, image, 0xffffffffu);
- } else if (radv_layout_can_fast_clear(image, src_layout, src_queue_mask) &&
- !radv_layout_can_fast_clear(image, dst_layout, dst_queue_mask)) {
- radv_fast_clear_flush_image_inplace(cmd_buffer, image, range);
- }
-}
-
void radv_initialize_dcc(struct radv_cmd_buffer *cmd_buffer,
struct radv_image *image, uint32_t value)
{
RADV_CMD_FLAG_FLUSH_AND_INV_CB_META;
}
-static void radv_handle_dcc_image_transition(struct radv_cmd_buffer *cmd_buffer,
- struct radv_image *image,
- VkImageLayout src_layout,
- VkImageLayout dst_layout,
- unsigned src_queue_mask,
- unsigned dst_queue_mask,
- const VkImageSubresourceRange *range)
+/**
+ * Initialize DCC/FMASK/CMASK metadata for a color image.
+ */
+static void radv_init_color_image_metadata(struct radv_cmd_buffer *cmd_buffer,
+ struct radv_image *image,
+ VkImageLayout src_layout,
+ VkImageLayout dst_layout,
+ unsigned src_queue_mask,
+ unsigned dst_queue_mask)
+{
+ if (radv_image_has_cmask(image)) {
+ uint32_t value = 0xffffffffu; /* Fully expanded mode. */
+
+ /* TODO: clarify this. */
+ if (radv_image_has_fmask(image)) {
+ value = 0xccccccccu;
+ }
+
+ radv_initialise_cmask(cmd_buffer, image, value);
+ }
+
+ if (radv_image_has_dcc(image)) {
+ uint32_t value = 0xffffffffu; /* Fully expanded mode. */
+
+ if (radv_layout_dcc_compressed(image, dst_layout,
+ dst_queue_mask)) {
+ value = 0x20202020u;
+ }
+
+ radv_initialize_dcc(cmd_buffer, image, value);
+ }
+}
+
+/**
+ * Handle color image transitions for DCC/FMASK/CMASK.
+ */
+static void radv_handle_color_image_transition(struct radv_cmd_buffer *cmd_buffer,
+ struct radv_image *image,
+ VkImageLayout src_layout,
+ VkImageLayout dst_layout,
+ unsigned src_queue_mask,
+ unsigned dst_queue_mask,
+ const VkImageSubresourceRange *range)
{
- if (src_layout == VK_IMAGE_LAYOUT_PREINITIALIZED) {
- radv_initialize_dcc(cmd_buffer, image, 0xffffffffu);
- } else if (src_layout == VK_IMAGE_LAYOUT_UNDEFINED) {
- radv_initialize_dcc(cmd_buffer, image,
- radv_layout_dcc_compressed(image, dst_layout, dst_queue_mask) ?
- 0x20202020u : 0xffffffffu);
- } else if (radv_layout_dcc_compressed(image, src_layout, src_queue_mask) &&
- !radv_layout_dcc_compressed(image, dst_layout, dst_queue_mask)) {
- radv_decompress_dcc(cmd_buffer, image, range);
- } else if (radv_layout_can_fast_clear(image, src_layout, src_queue_mask) &&
- !radv_layout_can_fast_clear(image, dst_layout, dst_queue_mask)) {
- radv_fast_clear_flush_image_inplace(cmd_buffer, image, range);
+ if (src_layout == VK_IMAGE_LAYOUT_UNDEFINED) {
+ radv_init_color_image_metadata(cmd_buffer, image,
+ src_layout, dst_layout,
+ src_queue_mask, dst_queue_mask);
+ return;
+ }
+
+ if (radv_image_has_dcc(image)) {
+ if (src_layout == VK_IMAGE_LAYOUT_PREINITIALIZED) {
+ radv_initialize_dcc(cmd_buffer, image, 0xffffffffu);
+ } else if (radv_layout_dcc_compressed(image, src_layout, src_queue_mask) &&
+ !radv_layout_dcc_compressed(image, dst_layout, dst_queue_mask)) {
+ radv_decompress_dcc(cmd_buffer, image, range);
+ } else if (radv_layout_can_fast_clear(image, src_layout, src_queue_mask) &&
+ !radv_layout_can_fast_clear(image, dst_layout, dst_queue_mask)) {
+ radv_fast_clear_flush_image_inplace(cmd_buffer, image, range);
+ }
+ } else if (radv_image_has_cmask(image) || radv_image_has_fmask(image)) {
+ if (radv_layout_can_fast_clear(image, src_layout, src_queue_mask) &&
+ !radv_layout_can_fast_clear(image, dst_layout, dst_queue_mask)) {
+ radv_fast_clear_flush_image_inplace(cmd_buffer, image, range);
+ }
}
}
return;
}
- unsigned src_queue_mask = radv_image_queue_family_mask(image, src_family, cmd_buffer->queue_family_index);
- unsigned dst_queue_mask = radv_image_queue_family_mask(image, dst_family, cmd_buffer->queue_family_index);
-
- if (radv_image_has_htile(image))
- radv_handle_depth_image_transition(cmd_buffer, image, src_layout,
- dst_layout, src_queue_mask,
- dst_queue_mask, range,
- pending_clears);
+ unsigned src_queue_mask =
+ radv_image_queue_family_mask(image, src_family,
+ cmd_buffer->queue_family_index);
+ unsigned dst_queue_mask =
+ radv_image_queue_family_mask(image, dst_family,
+ cmd_buffer->queue_family_index);
- if (radv_image_has_cmask(image) || radv_image_has_fmask(image))
- radv_handle_cmask_image_transition(cmd_buffer, image, src_layout,
- dst_layout, src_queue_mask,
- dst_queue_mask, range);
-
- if (radv_image_has_dcc(image))
- radv_handle_dcc_image_transition(cmd_buffer, image, src_layout,
- dst_layout, src_queue_mask,
- dst_queue_mask, range);
+ if (vk_format_is_depth(image->vk_format)) {
+ radv_handle_depth_image_transition(cmd_buffer, image,
+ src_layout, dst_layout,
+ src_queue_mask, dst_queue_mask,
+ range, pending_clears);
+ } else {
+ radv_handle_color_image_transition(cmd_buffer, image,
+ src_layout, dst_layout,
+ src_queue_mask, dst_queue_mask,
+ range);
+ }
}
void radv_CmdPipelineBarrier(