File: amd_vcn_shared.c

package info (click to toggle)
intel-gpu-tools 2.2-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 63,368 kB
  • sloc: xml: 781,458; ansic: 360,567; python: 8,336; yacc: 2,781; perl: 1,196; sh: 1,177; lex: 487; asm: 227; lisp: 35; makefile: 30
file content (191 lines) | stat: -rw-r--r-- 6,830 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
// SPDX-License-Identifier: MIT
// Copyright 2025 Advanced Micro Devices, Inc.

#include "amd_vcn_shared.h"

bool
is_vcn_tests_enable(amdgpu_device_handle device_handle, struct mmd_shared_context *context)
{
	struct drm_amdgpu_info_hw_ip info;
	int r;

	r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_VCN_ENC, 0, &info);

	if (r)
		return false;

	context->vcn_ip_version_major = info.hw_ip_version_major;
	context->vcn_ip_version_minor = info.hw_ip_version_minor;
	context->enc_ring = !!info.available_rings;
	/* in vcn 4.0 it re-uses encoding queue as unified queue */
	if (context->vcn_ip_version_major >= 4) {
		context->vcn_unified_ring = true;
		context->vcn_dec_sw_ring = true;
		context->dec_ring = context->enc_ring;
	} else {
		r = amdgpu_query_hw_ip_info(device_handle, AMDGPU_HW_IP_VCN_DEC, 0, &info);
		context->dec_ring = !!info.available_rings;
	}

	if (!(context->dec_ring || context->enc_ring) ||
		(context->family_id < AMDGPU_FAMILY_RV &&
		(context->family_id == AMDGPU_FAMILY_AI &&
		(context->chip_id - context->chip_rev) < 0x32))) { /* Arcturus */
		igt_info("The ASIC does NOT support VCN, vcn test is disabled\n");
		return false;
	}

	if (context->family_id == AMDGPU_FAMILY_AI)
		context->enc_ring  = false;

	if (!context->dec_ring) {
		igt_info("VCN Tests DEC create disable\n");
		igt_info("VCN Tests DEC decode disable\n");
		igt_info("VCN Tests DEC destroy disable\n");
	}

	if (!context->enc_ring) {
		igt_info("VCN Tests ENC create disable\n");
		igt_info("VCN Tests ENC encode disable\n");
		igt_info("VCN Tests ENC destroy disable\n");
	}

	if (context->vcn_ip_version_major == 1) {
		context->vcn_reg_index = 0;
	} else if (context->vcn_ip_version_major == 2 && context->vcn_ip_version_minor == 0) {
		context->vcn_reg_index = 1;
	} else if ((context->vcn_ip_version_major == 2 && context->vcn_ip_version_minor >= 5) ||
			context->vcn_ip_version_major == 3) {
		context->vcn_reg_index = 2;
	}

	return true;
}

void
amdgpu_cs_sq_head(struct vcn_context *v_context, uint32_t *base, int *offset, bool enc)
{
	/* signature */
	*(base + (*offset)++) = 0x00000010;
	*(base + (*offset)++) = 0x30000002;
	v_context->ib_checksum = base + (*offset)++;
	v_context->ib_size_in_dw = base + (*offset)++;

	/* engine info */
	*(base + (*offset)++) = 0x00000010;
	*(base + (*offset)++) = 0x30000001;
	*(base + (*offset)++) = enc ? 2 : 3;
	*(base + (*offset)++) = 0x00000000;
}

void
amdgpu_cs_sq_ib_tail(struct vcn_context *v_context, uint32_t *end)
{
	uint32_t size_in_dw;
	uint32_t checksum = 0;

	/* if the pointers are invalid, no need to process */
	if (v_context->ib_checksum == NULL || v_context->ib_size_in_dw == NULL)
		return;

	size_in_dw = end - v_context->ib_size_in_dw - 1;
	*v_context->ib_size_in_dw = size_in_dw;
	*(v_context->ib_size_in_dw + 4) = size_in_dw * sizeof(uint32_t);

	for (int i = 0; i < size_in_dw; i++)
		checksum += *(v_context->ib_checksum + 2 + i);

	*v_context->ib_checksum = checksum;

	v_context->ib_checksum = NULL;
	v_context->ib_size_in_dw = NULL;
}

void
vcn_dec_cmd(struct mmd_shared_context *shared_context,
		struct mmd_context *context, struct vcn_context *v_context,
		uint64_t addr, unsigned int cmd, int *idx, enum decoder_error_type err_type)
{
	if (shared_context->vcn_dec_sw_ring == false) {
		context->ib_cpu[(*idx)++] = reg[shared_context->vcn_reg_index].data0;
		context->ib_cpu[(*idx)++] = addr;
		context->ib_cpu[(*idx)++] = reg[shared_context->vcn_reg_index].data1;
		context->ib_cpu[(*idx)++] = addr >> 32;
		context->ib_cpu[(*idx)++] = reg[shared_context->vcn_reg_index].cmd;
		context->ib_cpu[(*idx)++] = cmd << 1;
		return;
	}

	/* Support decode software ring message */
	if (!(*idx)) {
		struct rvcn_decode_ib_package *ib_header;

		if (shared_context->vcn_unified_ring)
			amdgpu_cs_sq_head(v_context, context->ib_cpu, idx, false);

		ib_header = (struct rvcn_decode_ib_package *)&context->ib_cpu[*idx];
		if (err_type == INVALID_DECODER_IB_SIZE)
			ib_header->package_size = 0;
		else
			ib_header->package_size = sizeof(struct rvcn_decode_buffer) +
			sizeof(struct rvcn_decode_ib_package);

		(*idx)++;
		ib_header->package_type = (DECODE_IB_PARAM_DECODE_BUFFER);
		(*idx)++;

		v_context->decode_buffer = (struct rvcn_decode_buffer *)&(context->ib_cpu[*idx]);
		*idx += sizeof(struct rvcn_decode_buffer) / 4;
		memset(v_context->decode_buffer, 0, sizeof(struct rvcn_decode_buffer));
	}

	switch (cmd) {
	case DECODE_CMD_MSG_BUFFER:
		v_context->decode_buffer->valid_buf_flag |= DECODE_CMDBUF_FLAGS_MSG_BUFFER;
		v_context->decode_buffer->msg_buffer_address_hi = (addr >> 32);
		v_context->decode_buffer->msg_buffer_address_lo = (addr);
	break;
	case DECODE_CMD_DPB_BUFFER:
		v_context->decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_DPB_BUFFER);
		v_context->decode_buffer->dpb_buffer_address_hi = (addr >> 32);
		v_context->decode_buffer->dpb_buffer_address_lo = (addr);
	break;
	case DECODE_CMD_DECODING_TARGET_BUFFER:
		v_context->decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_DECODING_TARGET_BUFFER);
		v_context->decode_buffer->target_buffer_address_hi = (addr >> 32);
		v_context->decode_buffer->target_buffer_address_lo = (addr);
	break;
	case DECODE_CMD_FEEDBACK_BUFFER:
		v_context->decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_FEEDBACK_BUFFER);
		v_context->decode_buffer->feedback_buffer_address_hi = (addr >> 32);
		v_context->decode_buffer->feedback_buffer_address_lo = (addr);
	break;
	case DECODE_CMD_PROB_TBL_BUFFER:
		v_context->decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_PROB_TBL_BUFFER);
		v_context->decode_buffer->prob_tbl_buffer_address_hi = (addr >> 32);
		v_context->decode_buffer->prob_tbl_buffer_address_lo = (addr);
	break;
	case DECODE_CMD_SESSION_CONTEXT_BUFFER:
		v_context->decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_SESSION_CONTEXT_BUFFER);
		v_context->decode_buffer->session_contex_buffer_address_hi = (addr >> 32);
		v_context->decode_buffer->session_contex_buffer_address_lo = (addr);
	break;
	case DECODE_CMD_BITSTREAM_BUFFER:
		v_context->decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_BITSTREAM_BUFFER);
		v_context->decode_buffer->bitstream_buffer_address_hi = (addr >> 32);
		v_context->decode_buffer->bitstream_buffer_address_lo = (addr);
	break;
	case DECODE_CMD_IT_SCALING_TABLE_BUFFER:
		v_context->decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_IT_SCALING_BUFFER);
		v_context->decode_buffer->it_sclr_table_buffer_address_hi = (addr >> 32);
		v_context->decode_buffer->it_sclr_table_buffer_address_lo = (addr);
	break;
	case DECODE_CMD_CONTEXT_BUFFER:
		v_context->decode_buffer->valid_buf_flag |= (DECODE_CMDBUF_FLAGS_CONTEXT_BUFFER);
		v_context->decode_buffer->context_buffer_address_hi = (addr >> 32);
		v_context->decode_buffer->context_buffer_address_lo = (addr);
	break;
	default:
		igt_info("Not Supported!\n");
	}
}