提交 1e644d6d 编写于 作者: A Alex Deucher 提交者: Dave Airlie

drm/radeon/kms: re-emit full context state for evergreen blits

clear state doesn't seem to work properly in some cases

Fixes hangs in heavy 3D on some evergreen cards reported on
IRC.

May fix:
https://bugs.freedesktop.org/show_bug.cgi?id=33381
possibly others.
Signed-off-by: NAlex Deucher <alexdeucher@gmail.com>
Cc: stable@kernel.org
Signed-off-by: NDave Airlie <airlied@gmail.com>
上级 dca0d612
......@@ -232,7 +232,7 @@ draw_auto(struct radeon_device *rdev)
}
/* emits 30 */
/* emits 34 */
static void
set_default_state(struct radeon_device *rdev)
{
......@@ -245,6 +245,8 @@ 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:
......@@ -497,6 +499,14 @@ set_default_state(struct radeon_device *rdev)
radeon_ring_write(rdev, 0x00000000);
radeon_ring_write(rdev, 0x00000000);
/* 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);
}
static inline uint32_t i2f(uint32_t input)
......@@ -527,8 +537,10 @@ static inline uint32_t i2f(uint32_t input)
int evergreen_blit_init(struct radeon_device *rdev)
{
u32 obj_size;
int r;
int r, dwords;
void *ptr;
u32 packet2s[16];
int num_packet2s = 0;
/* pin copy shader into vram if already initialized */
if (rdev->r600_blit.shader_obj)
......@@ -536,8 +548,17 @@ 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 = 0;
obj_size = 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.vs_offset = obj_size;
obj_size += evergreen_vs_size * 4;
......@@ -567,6 +588,12 @@ 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);
......@@ -652,7 +679,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 += 46; /* shaders + def state */
ring_size += 50; /* shaders + def state */
ring_size += 10; /* fence emit for VB IB */
ring_size += 5; /* done copy */
ring_size += 10; /* fence emit for done copy */
......@@ -660,7 +687,7 @@ int evergreen_blit_prepare_copy(struct radeon_device *rdev, int size_bytes)
if (r)
return r;
set_default_state(rdev); /* 30 */
set_default_state(rdev); /* 34 */
set_shaders(rdev); /* 16 */
return 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册