[PATCH] drm/radeon/kms/evergreen: set the clear state to the blit state

Alex Deucher alexdeucher at gmail.com
Thu Oct 21 10:31:38 PDT 2010


The hw stores a default clear state for registers in the context
range that can be initialized when the CP is set up.  Set the
blit state as the default clear state and use the CLEAR_STATE
packet to load the blit state rather than loading it from an IB.
This reduces overhead when doing bo moves using the 3D engine.

Signed-off-by: Alex Deucher <alexdeucher at gmail.com>
---
 drivers/gpu/drm/radeon/evergreen.c              |   38 ++++++++++++---
 drivers/gpu/drm/radeon/evergreen_blit_kms.c     |   60 +++++++++++------------
 drivers/gpu/drm/radeon/evergreen_blit_shaders.c |   19 ++------
 drivers/gpu/drm/radeon/evergreend.h             |    2 +
 4 files changed, 65 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 541ae39..2cee695 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -32,6 +32,7 @@
 #include "atom.h"
 #include "avivod.h"
 #include "evergreen_reg.h"
+#include "evergreen_blit_shaders.h"
 
 #define EVERGREEN_PFP_UCODE_SIZE 1120
 #define EVERGREEN_PM4_UCODE_SIZE 1376
@@ -677,7 +678,7 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev)
 
 static int evergreen_cp_start(struct radeon_device *rdev)
 {
-	int r;
+	int r, i;
 	uint32_t cp_me;
 
 	r = radeon_ring_lock(rdev, 7);
@@ -697,16 +698,39 @@ static int evergreen_cp_start(struct radeon_device *rdev)
 	cp_me = 0xff;
 	WREG32(CP_ME_CNTL, cp_me);
 
-	r = radeon_ring_lock(rdev, 4);
+	r = radeon_ring_lock(rdev, evergreen_default_size + 15);
 	if (r) {
 		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
 		return r;
 	}
-	/* init some VGT regs */
-	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
-	radeon_ring_write(rdev, (VGT_VERTEX_REUSE_BLOCK_CNTL - PACKET3_SET_CONTEXT_REG_START) >> 2);
-	radeon_ring_write(rdev, 0xe);
-	radeon_ring_write(rdev, 0x10);
+
+	/* setup clear context state */
+	radeon_ring_write(rdev, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
+	radeon_ring_write(rdev, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
+
+	for (i = 0; i < evergreen_default_size; i++)
+		radeon_ring_write(rdev, evergreen_default_state[i]);
+
+	radeon_ring_write(rdev, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
+	radeon_ring_write(rdev, PACKET3_PREAMBLE_END_CLEAR_STATE);
+
+	/* set clear context state */
+	radeon_ring_write(rdev, PACKET3(PACKET3_CLEAR_STATE, 0));
+	radeon_ring_write(rdev, 0);
+
+	/* SQ_VTX_BASE_VTX_LOC */
+	radeon_ring_write(rdev, 0xc0026f00);
+	radeon_ring_write(rdev, 0x00000000);
+	radeon_ring_write(rdev, 0x00000000);
+	radeon_ring_write(rdev, 0x00000000);
+
+	/* Clear consts */
+	radeon_ring_write(rdev, 0xc0036f00);
+	radeon_ring_write(rdev, 0x00000bc4);
+	radeon_ring_write(rdev, 0xffffffff);
+	radeon_ring_write(rdev, 0xffffffff);
+	radeon_ring_write(rdev, 0xffffffff);
+
 	radeon_ring_unlock_commit(rdev);
 
 	return 0;
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
index 2eeb29d..ac3b6dd 100644
--- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c
+++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c
@@ -230,7 +230,7 @@ draw_auto(struct radeon_device *rdev)
 
 }
 
-/* emits 20 */
+/* emits 30 */
 static void
 set_default_state(struct radeon_device *rdev)
 {
@@ -243,8 +243,6 @@ set_default_state(struct radeon_device *rdev)
 	int num_hs_threads, num_ls_threads;
 	int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries;
 	int num_hs_stack_entries, num_ls_stack_entries;
-	u64 gpu_addr;
-	int dwords;
 
 	switch (rdev->family) {
 	case CHIP_CEDAR:
@@ -369,13 +367,9 @@ set_default_state(struct radeon_device *rdev)
 	sq_stack_resource_mgmt_3 = (NUM_HS_STACK_ENTRIES(num_hs_stack_entries) |
 				    NUM_LS_STACK_ENTRIES(num_ls_stack_entries));
 
-	/* emit an IB pointing at default state */
-	dwords = ALIGN(rdev->r600_blit.state_len, 0x10);
-	gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset;
-	radeon_ring_write(rdev, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
-	radeon_ring_write(rdev, gpu_addr & 0xFFFFFFFC);
-	radeon_ring_write(rdev, upper_32_bits(gpu_addr) & 0xFF);
-	radeon_ring_write(rdev, dwords);
+	/* set clear context state */
+	radeon_ring_write(rdev, PACKET3(PACKET3_CLEAR_STATE, 0));
+	radeon_ring_write(rdev, 0);
 
 	/* disable dyn gprs */
 	radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1));
@@ -396,6 +390,25 @@ set_default_state(struct radeon_device *rdev)
 	radeon_ring_write(rdev, sq_stack_resource_mgmt_1);
 	radeon_ring_write(rdev, sq_stack_resource_mgmt_2);
 	radeon_ring_write(rdev, sq_stack_resource_mgmt_3);
+
+	/* CONTEXT_CONTROL */
+	radeon_ring_write(rdev, 0xc0012800);
+	radeon_ring_write(rdev, 0x80000000);
+	radeon_ring_write(rdev, 0x80000000);
+
+	/* SQ_VTX_BASE_VTX_LOC */
+	radeon_ring_write(rdev, 0xc0026f00);
+	radeon_ring_write(rdev, 0x00000000);
+	radeon_ring_write(rdev, 0x00000000);
+	radeon_ring_write(rdev, 0x00000000);
+
+	/* SET_SAMPLER */
+	radeon_ring_write(rdev, 0xc0036e00);
+	radeon_ring_write(rdev, 0x00000000);
+	radeon_ring_write(rdev, 0x00000012);
+	radeon_ring_write(rdev, 0x00000000);
+	radeon_ring_write(rdev, 0x00000000);
+
 }
 
 static inline uint32_t i2f(uint32_t input)
@@ -426,10 +439,8 @@ static inline uint32_t i2f(uint32_t input)
 int evergreen_blit_init(struct radeon_device *rdev)
 {
 	u32 obj_size;
-	int r, dwords;
+	int r;
 	void *ptr;
-	u32 packet2s[16];
-	int num_packet2s = 0;
 
 	/* pin copy shader into vram if already initialized */
 	if (rdev->r600_blit.shader_obj)
@@ -437,17 +448,8 @@ int evergreen_blit_init(struct radeon_device *rdev)
 
 	mutex_init(&rdev->r600_blit.mutex);
 	rdev->r600_blit.state_offset = 0;
-
-	rdev->r600_blit.state_len = evergreen_default_size;
-
-	dwords = rdev->r600_blit.state_len;
-	while (dwords & 0xf) {
-		packet2s[num_packet2s++] = PACKET2(0);
-		dwords++;
-	}
-
-	obj_size = dwords * 4;
-	obj_size = ALIGN(obj_size, 256);
+	rdev->r600_blit.state_len = 0;
+	obj_size = 0;
 
 	rdev->r600_blit.vs_offset = obj_size;
 	obj_size += evergreen_vs_size * 4;
@@ -477,12 +479,6 @@ int evergreen_blit_init(struct radeon_device *rdev)
 		return r;
 	}
 
-	memcpy_toio(ptr + rdev->r600_blit.state_offset,
-		    evergreen_default_state, rdev->r600_blit.state_len * 4);
-
-	if (num_packet2s)
-		memcpy_toio(ptr + rdev->r600_blit.state_offset + (rdev->r600_blit.state_len * 4),
-			    packet2s, num_packet2s * 4);
 	memcpy(ptr + rdev->r600_blit.vs_offset, evergreen_vs, evergreen_vs_size * 4);
 	memcpy(ptr + rdev->r600_blit.ps_offset, evergreen_ps, evergreen_ps_size * 4);
 	radeon_bo_kunmap(rdev->r600_blit.shader_obj);
@@ -568,7 +564,7 @@ int evergreen_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
 	/* calculate number of loops correctly */
 	ring_size = num_loops * dwords_per_loop;
 	/* set default  + shaders */
-	ring_size += 36; /* shaders + def state */
+	ring_size += 46; /* shaders + def state */
 	ring_size += 10; /* fence emit for VB IB */
 	ring_size += 5; /* done copy */
 	ring_size += 10; /* fence emit for done copy */
@@ -576,7 +572,7 @@ int evergreen_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
 	if (r)
 		return r;
 
-	set_default_state(rdev); /* 20 */
+	set_default_state(rdev); /* 30 */
 	set_shaders(rdev); /* 16 */
 	return 0;
 }
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_shaders.c b/drivers/gpu/drm/radeon/evergreen_blit_shaders.c
index 5d50450..ef1d28c 100644
--- a/drivers/gpu/drm/radeon/evergreen_blit_shaders.c
+++ b/drivers/gpu/drm/radeon/evergreen_blit_shaders.c
@@ -39,10 +39,6 @@
 
 const u32 evergreen_default_state[] =
 {
-	0xc0012800, /* CONTEXT_CONTROL */
-	0x80000000,
-	0x80000000,
-
 	0xc0016900,
 	0x0000023b,
 	0x00000000, /* SQ_LDS_ALLOC_PS */
@@ -63,17 +59,11 @@ const u32 evergreen_default_state[] =
 	0x00000000,
 	0x00000000,
 
-	0xc0026f00,
-	0x00000000,
-	0x00000000, /* SQ_VTX_BASE_VTX_LOC */
-	0x00000000,
-
 	0xc0026900,
 	0x00000010,
 	0x00000000, /* DB_Z_INFO */
 	0x00000000, /* DB_STENCIL_INFO */
 
-
 	0xc0016900,
 	0x00000200,
 	0x00000000, /* DB_DEPTH_CONTROL */
@@ -303,11 +293,10 @@ const u32 evergreen_default_state[] =
 	0x00000000, /*  */
 	0x00000000, /*  */
 
-	0xc0036e00, /* SET_SAMPLER */
-	0x00000000,
-	0x00000012,
-	0x00000000,
-	0x00000000,
+	0xc0026900,
+	0x00000316,
+	0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */
+	0x00000010, /*  */
 };
 
 const u32 evergreen_vs[] =
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h
index 319aa97..c41b49c 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -645,6 +645,8 @@
 #define	PACKET3_EVENT_WRITE_EOP				0x47
 #define	PACKET3_EVENT_WRITE_EOS				0x48
 #define	PACKET3_PREAMBLE_CNTL				0x4A
+#              define PACKET3_PREAMBLE_BEGIN_CLEAR_STATE     (2 << 28)
+#              define PACKET3_PREAMBLE_END_CLEAR_STATE       (3 << 28)
 #define	PACKET3_RB_OFFSET				0x4B
 #define	PACKET3_ALU_PS_CONST_BUFFER_COPY		0x4C
 #define	PACKET3_ALU_VS_CONST_BUFFER_COPY		0x4D
-- 
1.7.1.1



More information about the dri-devel mailing list