[igt-dev] [PATCH 4/7] lib/amdgpu: add simple buf management to emit commands

vitaly.prosyak at amd.com vitaly.prosyak at amd.com
Thu Jul 7 18:28:08 UTC 2022


From: Vitaly Prosyak <vitaly.prosyak at amd.com>

There is no binding yet between ASIC reg and buffer
management. We are going to add based on the next tests.

Signed-off-by: Vitaly Prosyak <vitaly.prosyak at amd.com>
---
 lib/amdgpu/amd_ip_blocks.c | 87 ++++++++++++++++++++++++++++++++++++++
 lib/amdgpu/amd_ip_blocks.h | 19 +++++++++
 2 files changed, 106 insertions(+)

diff --git a/lib/amdgpu/amd_ip_blocks.c b/lib/amdgpu/amd_ip_blocks.c
index 89b19e39..795eb198 100644
--- a/lib/amdgpu/amd_ip_blocks.c
+++ b/lib/amdgpu/amd_ip_blocks.c
@@ -406,9 +406,96 @@ get_ip_block(amdgpu_device_handle device, enum amd_ip_block_type type)
 	return NULL;
 }
 
+static int
+cmd_allocate_buf(struct amdgpu_cmd_base  *base, uint32_t size_dw)
+{
+	if (size_dw > base->max_dw) {
+		if (base->buf) {
+			free(base->buf);
+			base->buf = NULL;
+			base->max_dw = 0;
+			base->cdw = 0;
+		}
+		base->buf = calloc(4, size_dw);
+		if (!base->buf)
+			return -1;
+		base->max_dw = size_dw;
+		base->cdw = 0;
+	}
+	return 0;
+}
+
+static int
+cmd_attach_buf(struct amdgpu_cmd_base  *base, void *ptr, uint32_t size_bytes)
+{
+	if (base->buf && base->is_assigned_buf)
+		return -1;
 
+	if (base->buf) {
+		free(base->buf);
+		base->buf = NULL;
+		base->max_dw = 0;
+		base->cdw = 0;
+	}
+	assert(ptr != NULL);
+	base->buf = (uint32_t *)ptr;
+	base->max_dw = size_bytes>>2;
+	base->cdw = 0;
+	base->is_assigned_buf = true; /* allocated externally , no free */
+	return 0;
+}
 
+static void
+cmd_emit(struct amdgpu_cmd_base  *base, uint32_t value)
+{
+	assert(base->cdw <  base->max_dw  );
+	base->buf[base->cdw++] = value;
+}
 
+static void
+cmd_emit_buf(struct amdgpu_cmd_base  *base, const void *ptr, uint32_t offset_bytes, uint32_t size_bytes)
+{
+	/* we assume that caller knows what is doing and we loose the buffer current index */
+	/* we may do this later abstract the internal index */
+	assert(base->cdw + ((offset_bytes + size_bytes)>>2) <  base->max_dw  );
+	memcpy(base->buf + offset_bytes , ptr, size_bytes);
+}
+
+struct amdgpu_cmd_base *
+get_cmd_base(void)
+{
+	struct amdgpu_cmd_base *base = calloc(1 ,sizeof(*base));
+
+	base->cdw = 0;
+	base->max_dw = 0;
+	base->buf = NULL;
+	base->is_assigned_buf = false;
+
+	base->allocate_buf = cmd_allocate_buf;
+	base->attach_buf = cmd_attach_buf;
+	base->emit = cmd_emit;
+	base->emit_buf = cmd_emit_buf;
+
+	return base;
+}
+
+void
+free_cmd_base(struct amdgpu_cmd_base * base)
+{
+	if (base) {
+		if (base->buf && base->is_assigned_buf == false)
+			free(base->buf);
+		free(base);
+	}
+
+}
+
+void
+append_cmd_base(struct amdgpu_cmd_base *base, uint32_t mask, uint32_t cmd)
+{
+	while(base->cdw & mask)
+		base->emit(base, cmd);
+}
 
 /*
  * GFX: 8.x
diff --git a/lib/amdgpu/amd_ip_blocks.h b/lib/amdgpu/amd_ip_blocks.h
index c16ad179..83809efe 100644
--- a/lib/amdgpu/amd_ip_blocks.h
+++ b/lib/amdgpu/amd_ip_blocks.h
@@ -112,5 +112,24 @@ setup_amdgpu_ip_blocks(uint32_t major, uint32_t minor, struct amdgpu_gpu_info *a
 const struct amdgpu_ip_block_version *
 get_ip_block(amdgpu_device_handle device, enum amd_ip_block_type type);
 
+struct amdgpu_cmd_base {
+	uint32_t cdw;  /* Number of used dwords. */
+	uint32_t max_dw; /* Maximum number of dwords. */
+	uint32_t *buf; /* The base pointer of the chunk. */
+	bool is_assigned_buf;
+
+	/* functions */
+	int (*allocate_buf)(struct amdgpu_cmd_base  *base, uint32_t size);
+	int (*attach_buf)(struct amdgpu_cmd_base  *base, void *ptr, uint32_t size_bytes);
+	void (*emit)(struct amdgpu_cmd_base  *base, uint32_t value);
+	void (*emit_buf)(struct amdgpu_cmd_base  *base, const void *ptr, uint32_t offset_bytes, uint32_t size_bytes);
+};
+
+struct amdgpu_cmd_base* get_cmd_base(void);
+
+void free_cmd_base(struct amdgpu_cmd_base *base);
+
+void
+append_cmd_base(struct amdgpu_cmd_base *base, uint32_t mask, uint32_t cmd);
 
 #endif
-- 
2.25.1



More information about the igt-dev mailing list