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

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@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
Alex Deucher 2010-10-21 13:31:38 -04:00 committed by Dave Airlie
parent c3cceeddf0
commit 2281a378e1
4 changed files with 65 additions and 54 deletions

View File

@ -32,6 +32,7 @@
#include "atom.h" #include "atom.h"
#include "avivod.h" #include "avivod.h"
#include "evergreen_reg.h" #include "evergreen_reg.h"
#include "evergreen_blit_shaders.h"
#define EVERGREEN_PFP_UCODE_SIZE 1120 #define EVERGREEN_PFP_UCODE_SIZE 1120
#define EVERGREEN_PM4_UCODE_SIZE 1376 #define EVERGREEN_PM4_UCODE_SIZE 1376
@ -1112,7 +1113,7 @@ static int evergreen_cp_load_microcode(struct radeon_device *rdev)
static int evergreen_cp_start(struct radeon_device *rdev) static int evergreen_cp_start(struct radeon_device *rdev)
{ {
int r; int r, i;
uint32_t cp_me; uint32_t cp_me;
r = radeon_ring_lock(rdev, 7); r = radeon_ring_lock(rdev, 7);
@ -1132,16 +1133,39 @@ static int evergreen_cp_start(struct radeon_device *rdev)
cp_me = 0xff; cp_me = 0xff;
WREG32(CP_ME_CNTL, cp_me); WREG32(CP_ME_CNTL, cp_me);
r = radeon_ring_lock(rdev, 4); r = radeon_ring_lock(rdev, evergreen_default_size + 15);
if (r) { if (r) {
DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
return r; return r;
} }
/* init some VGT regs */
radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); /* setup clear context state */
radeon_ring_write(rdev, (VGT_VERTEX_REUSE_BLOCK_CNTL - PACKET3_SET_CONTEXT_REG_START) >> 2); radeon_ring_write(rdev, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
radeon_ring_write(rdev, 0xe); radeon_ring_write(rdev, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
radeon_ring_write(rdev, 0x10);
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); radeon_ring_unlock_commit(rdev);
return 0; return 0;

View File

@ -230,7 +230,7 @@ draw_auto(struct radeon_device *rdev)
} }
/* emits 20 */ /* emits 30 */
static void static void
set_default_state(struct radeon_device *rdev) 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_hs_threads, num_ls_threads;
int num_ps_stack_entries, num_vs_stack_entries, num_gs_stack_entries, num_es_stack_entries; 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; int num_hs_stack_entries, num_ls_stack_entries;
u64 gpu_addr;
int dwords;
switch (rdev->family) { switch (rdev->family) {
case CHIP_CEDAR: 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) | sq_stack_resource_mgmt_3 = (NUM_HS_STACK_ENTRIES(num_hs_stack_entries) |
NUM_LS_STACK_ENTRIES(num_ls_stack_entries)); NUM_LS_STACK_ENTRIES(num_ls_stack_entries));
/* emit an IB pointing at default state */ /* set clear context state */
dwords = ALIGN(rdev->r600_blit.state_len, 0x10); radeon_ring_write(rdev, PACKET3(PACKET3_CLEAR_STATE, 0));
gpu_addr = rdev->r600_blit.shader_gpu_addr + rdev->r600_blit.state_offset; radeon_ring_write(rdev, 0);
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);
/* disable dyn gprs */ /* disable dyn gprs */
radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 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_1);
radeon_ring_write(rdev, sq_stack_resource_mgmt_2); radeon_ring_write(rdev, sq_stack_resource_mgmt_2);
radeon_ring_write(rdev, sq_stack_resource_mgmt_3); 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) 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) int evergreen_blit_init(struct radeon_device *rdev)
{ {
u32 obj_size; u32 obj_size;
int r, dwords; int r;
void *ptr; void *ptr;
u32 packet2s[16];
int num_packet2s = 0;
/* pin copy shader into vram if already initialized */ /* pin copy shader into vram if already initialized */
if (rdev->r600_blit.shader_obj) if (rdev->r600_blit.shader_obj)
@ -437,17 +448,8 @@ int evergreen_blit_init(struct radeon_device *rdev)
mutex_init(&rdev->r600_blit.mutex); mutex_init(&rdev->r600_blit.mutex);
rdev->r600_blit.state_offset = 0; rdev->r600_blit.state_offset = 0;
rdev->r600_blit.state_len = 0;
rdev->r600_blit.state_len = evergreen_default_size; obj_size = 0;
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.vs_offset = obj_size; rdev->r600_blit.vs_offset = obj_size;
obj_size += evergreen_vs_size * 4; obj_size += evergreen_vs_size * 4;
@ -477,12 +479,6 @@ int evergreen_blit_init(struct radeon_device *rdev)
return r; 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.vs_offset, evergreen_vs, evergreen_vs_size * 4);
memcpy(ptr + rdev->r600_blit.ps_offset, evergreen_ps, evergreen_ps_size * 4); memcpy(ptr + rdev->r600_blit.ps_offset, evergreen_ps, evergreen_ps_size * 4);
radeon_bo_kunmap(rdev->r600_blit.shader_obj); radeon_bo_kunmap(rdev->r600_blit.shader_obj);
@ -566,7 +562,7 @@ int evergreen_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
/* calculate number of loops correctly */ /* calculate number of loops correctly */
ring_size = num_loops * dwords_per_loop; ring_size = num_loops * dwords_per_loop;
/* set default + shaders */ /* 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 += 10; /* fence emit for VB IB */
ring_size += 5; /* done copy */ ring_size += 5; /* done copy */
ring_size += 10; /* fence emit for done copy */ ring_size += 10; /* fence emit for done copy */
@ -574,7 +570,7 @@ int evergreen_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
if (r) if (r)
return r; return r;
set_default_state(rdev); /* 20 */ set_default_state(rdev); /* 30 */
set_shaders(rdev); /* 16 */ set_shaders(rdev); /* 16 */
return 0; return 0;
} }

View File

@ -39,10 +39,6 @@
const u32 evergreen_default_state[] = const u32 evergreen_default_state[] =
{ {
0xc0012800, /* CONTEXT_CONTROL */
0x80000000,
0x80000000,
0xc0016900, 0xc0016900,
0x0000023b, 0x0000023b,
0x00000000, /* SQ_LDS_ALLOC_PS */ 0x00000000, /* SQ_LDS_ALLOC_PS */
@ -63,17 +59,11 @@ const u32 evergreen_default_state[] =
0x00000000, 0x00000000,
0x00000000, 0x00000000,
0xc0026f00,
0x00000000,
0x00000000, /* SQ_VTX_BASE_VTX_LOC */
0x00000000,
0xc0026900, 0xc0026900,
0x00000010, 0x00000010,
0x00000000, /* DB_Z_INFO */ 0x00000000, /* DB_Z_INFO */
0x00000000, /* DB_STENCIL_INFO */ 0x00000000, /* DB_STENCIL_INFO */
0xc0016900, 0xc0016900,
0x00000200, 0x00000200,
0x00000000, /* DB_DEPTH_CONTROL */ 0x00000000, /* DB_DEPTH_CONTROL */
@ -303,11 +293,10 @@ const u32 evergreen_default_state[] =
0x00000000, /* */ 0x00000000, /* */
0x00000000, /* */ 0x00000000, /* */
0xc0036e00, /* SET_SAMPLER */ 0xc0026900,
0x00000000, 0x00000316,
0x00000012, 0x0000000e, /* VGT_VERTEX_REUSE_BLOCK_CNTL */
0x00000000, 0x00000010, /* */
0x00000000,
}; };
const u32 evergreen_vs[] = const u32 evergreen_vs[] =

View File

@ -658,6 +658,8 @@
#define PACKET3_EVENT_WRITE_EOP 0x47 #define PACKET3_EVENT_WRITE_EOP 0x47
#define PACKET3_EVENT_WRITE_EOS 0x48 #define PACKET3_EVENT_WRITE_EOS 0x48
#define PACKET3_PREAMBLE_CNTL 0x4A #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_RB_OFFSET 0x4B
#define PACKET3_ALU_PS_CONST_BUFFER_COPY 0x4C #define PACKET3_ALU_PS_CONST_BUFFER_COPY 0x4C
#define PACKET3_ALU_VS_CONST_BUFFER_COPY 0x4D #define PACKET3_ALU_VS_CONST_BUFFER_COPY 0x4D