diff --git a/src/amd/common/ac_vcn.h b/src/amd/common/ac_vcn.h index a5a73b4bbae..a6e1e22259b 100644 --- a/src/amd/common/ac_vcn.h +++ b/src/amd/common/ac_vcn.h @@ -28,15 +28,29 @@ #define RADEON_VCN_ENGINE_INFO (0x30000001) #define RADEON_VCN_SIGNATURE (0x30000002) +#define RADEON_VCN_ENGINE_TYPE_COMMON (0x00000001) #define RADEON_VCN_ENGINE_TYPE_ENCODE (0x00000002) #define RADEON_VCN_ENGINE_TYPE_DECODE (0x00000003) #define RADEON_VCN_ENGINE_INFO_SIZE (0x00000010) #define RADEON_VCN_SIGNATURE_SIZE (0x00000010) +#define RADEON_VCN_IB_COMMON_OP_WRITEMEMORY (0x33000001) + struct rvcn_sq_var { unsigned int *ib_total_size_in_dw; unsigned int *ib_checksum; }; +struct rvcn_cmn_engine_ib_package { + unsigned int package_size; + unsigned int package_type; +}; + +struct rvcn_cmn_engine_op_writememory { + unsigned int dest_addr_lo; // Low address of memory + unsigned int dest_addr_hi; // High address of memory + unsigned int data; // data to be written +}; + #endif diff --git a/src/amd/vulkan/radv_cmd_buffer.c b/src/amd/vulkan/radv_cmd_buffer.c index 836542be75c..68b14660542 100644 --- a/src/amd/vulkan/radv_cmd_buffer.c +++ b/src/amd/vulkan/radv_cmd_buffer.c @@ -13052,8 +13052,10 @@ write_event(struct radv_cmd_buffer *cmd_buffer, struct radv_event *event, VkPipe struct radeon_cmdbuf *cs = cmd_buffer->cs; uint64_t va = radv_buffer_get_va(event->bo); - if (cmd_buffer->qf == RADV_QUEUE_VIDEO_DEC || cmd_buffer->qf == RADV_QUEUE_VIDEO_ENC) + if (cmd_buffer->qf == RADV_QUEUE_VIDEO_DEC || cmd_buffer->qf == RADV_QUEUE_VIDEO_ENC) { + radv_vcn_write_event(cmd_buffer, event, value); return; + } radv_emit_cache_flush(cmd_buffer); diff --git a/src/amd/vulkan/radv_video.c b/src/amd/vulkan/radv_video.c index f8bb0204fa5..590435d877c 100644 --- a/src/amd/vulkan/radv_video.c +++ b/src/amd/vulkan/radv_video.c @@ -61,7 +61,7 @@ radv_vid_buffer_upload_alloc(struct radv_cmd_buffer *cmd_buffer, unsigned size, /* vcn unified queue (sq) ib header */ void -radv_vcn_sq_header(struct radeon_cmdbuf *cs, struct rvcn_sq_var *sq, bool enc) +radv_vcn_sq_header(struct radeon_cmdbuf *cs, struct rvcn_sq_var *sq, unsigned type) { /* vcn ib signature */ radeon_emit(cs, RADEON_VCN_SIGNATURE_SIZE); @@ -74,7 +74,7 @@ radv_vcn_sq_header(struct radeon_cmdbuf *cs, struct rvcn_sq_var *sq, bool enc) /* vcn ib engine info */ radeon_emit(cs, RADEON_VCN_ENGINE_INFO_SIZE); radeon_emit(cs, RADEON_VCN_ENGINE_INFO); - radeon_emit(cs, enc ? RADEON_VCN_ENGINE_TYPE_ENCODE : RADEON_VCN_ENGINE_TYPE_DECODE); + radeon_emit(cs, type); radeon_emit(cs, 0); } @@ -99,13 +99,44 @@ radv_vcn_sq_tail(struct radeon_cmdbuf *cs, struct rvcn_sq_var *sq) *sq->ib_checksum = checksum; } +void +radv_vcn_write_event(struct radv_cmd_buffer *cmd_buffer, struct radv_event *event, unsigned value) +{ + struct radv_device *device = radv_cmd_buffer_device(cmd_buffer); + struct radv_physical_device *pdev = radv_device_physical(device); + struct rvcn_sq_var sq; + struct radeon_cmdbuf *cs = cmd_buffer->cs; + + if (pdev->vid_decode_ip != AMD_IP_VCN_UNIFIED) + return; + + radv_cs_add_buffer(device->ws, cs, event->bo); + uint64_t va = radv_buffer_get_va(event->bo); + + radeon_check_space(device->ws, cs, 256); + radv_vcn_sq_header(cs, &sq, RADEON_VCN_ENGINE_TYPE_COMMON); + struct rvcn_cmn_engine_ib_package *ib_header = (struct rvcn_cmn_engine_ib_package *)&(cs->buf[cs->cdw]); + ib_header->package_size = sizeof(struct rvcn_cmn_engine_ib_package) + sizeof(struct rvcn_cmn_engine_op_writememory); + cs->cdw++; + ib_header->package_type = RADEON_VCN_IB_COMMON_OP_WRITEMEMORY; + cs->cdw++; + + struct rvcn_cmn_engine_op_writememory *write_memory = (struct rvcn_cmn_engine_op_writememory *)&(cs->buf[cs->cdw]); + write_memory->dest_addr_lo = va & 0xffffffff; + write_memory->dest_addr_hi = va >> 32; + write_memory->data = value; + + cs->cdw += sizeof(*write_memory) / 4; + radv_vcn_sq_tail(cs, &sq); +} + static void radv_vcn_sq_start(struct radv_cmd_buffer *cmd_buffer) { struct radv_device *device = radv_cmd_buffer_device(cmd_buffer); radeon_check_space(device->ws, cmd_buffer->cs, 256); - radv_vcn_sq_header(cmd_buffer->cs, &cmd_buffer->video.sq, false); + radv_vcn_sq_header(cmd_buffer->cs, &cmd_buffer->video.sq, RADEON_VCN_ENGINE_TYPE_DECODE); rvcn_decode_ib_package_t *ib_header = (rvcn_decode_ib_package_t *)&(cmd_buffer->cs->buf[cmd_buffer->cs->cdw]); ib_header->package_size = sizeof(struct rvcn_decode_buffer_s) + sizeof(struct rvcn_decode_ib_package_s); cmd_buffer->cs->cdw++; diff --git a/src/amd/vulkan/radv_video.h b/src/amd/vulkan/radv_video.h index 2ef442fd9f2..2cfe6f44406 100644 --- a/src/amd/vulkan/radv_video.h +++ b/src/amd/vulkan/radv_video.h @@ -12,6 +12,7 @@ #define RADV_VIDEO_H #include "vk_video.h" +#include "radv_event.h" #include "ac_vcn.h" @@ -70,9 +71,10 @@ void radv_init_physical_device_decoder(struct radv_physical_device *pdev); void radv_video_get_profile_alignments(struct radv_physical_device *pdev, const VkVideoProfileListInfoKHR *profile_list, uint32_t *width_align_out, uint32_t *height_align_out); -void radv_vcn_sq_header(struct radeon_cmdbuf *cs, struct rvcn_sq_var *sq, bool enc); +void radv_vcn_sq_header(struct radeon_cmdbuf *cs, struct rvcn_sq_var *sq, unsigned type); void radv_vcn_sq_tail(struct radeon_cmdbuf *cs, struct rvcn_sq_var *sq); +void radv_vcn_write_event(struct radv_cmd_buffer *cmd_buffer, struct radv_event *event, unsigned value); void radv_init_physical_device_encoder(struct radv_physical_device *pdevice); void radv_probe_video_encode(struct radv_physical_device *pdev); diff --git a/src/amd/vulkan/radv_video_enc.c b/src/amd/vulkan/radv_video_enc.c index dc584e0c423..e36b4cf4665 100644 --- a/src/amd/vulkan/radv_video_enc.c +++ b/src/amd/vulkan/radv_video_enc.c @@ -2012,7 +2012,7 @@ radv_video_enc_begin_coding(struct radv_cmd_buffer *cmd_buffer) radeon_check_space(device->ws, cmd_buffer->cs, 1024); if (pdev->enc_hw_ver >= RADV_VIDEO_ENC_HW_4) - radv_vcn_sq_header(cmd_buffer->cs, &cmd_buffer->video.sq, true); + radv_vcn_sq_header(cmd_buffer->cs, &cmd_buffer->video.sq, RADEON_VCN_ENGINE_TYPE_ENCODE); } void