drm/radeon/kms: cleanup r600 blit code
reorganize the code such that only the primitives (i.e., the functions that load the CP ring) are hardware specific; dynamically link the primitives in a (new) pointer structure inside r600_blit at blit initialization time so that the functions that control the blit operations can be made common for r600 and evergreen parts Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
This commit is contained in:
parent
638dd7db59
commit
8eec9d6f74
|
@ -44,7 +44,6 @@
|
||||||
|
|
||||||
#define RECT_UNIT_H 32
|
#define RECT_UNIT_H 32
|
||||||
#define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H)
|
#define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H)
|
||||||
#define MAX_RECT_DIM 8192
|
|
||||||
|
|
||||||
/* emits 21 on rv770+, 23 on r600 */
|
/* emits 21 on rv770+, 23 on r600 */
|
||||||
static void
|
static void
|
||||||
|
@ -491,6 +490,27 @@ int r600_blit_init(struct radeon_device *rdev)
|
||||||
u32 packet2s[16];
|
u32 packet2s[16];
|
||||||
int num_packet2s = 0;
|
int num_packet2s = 0;
|
||||||
|
|
||||||
|
rdev->r600_blit.primitives.set_render_target = set_render_target;
|
||||||
|
rdev->r600_blit.primitives.cp_set_surface_sync = cp_set_surface_sync;
|
||||||
|
rdev->r600_blit.primitives.set_shaders = set_shaders;
|
||||||
|
rdev->r600_blit.primitives.set_vtx_resource = set_vtx_resource;
|
||||||
|
rdev->r600_blit.primitives.set_tex_resource = set_tex_resource;
|
||||||
|
rdev->r600_blit.primitives.set_scissors = set_scissors;
|
||||||
|
rdev->r600_blit.primitives.draw_auto = draw_auto;
|
||||||
|
rdev->r600_blit.primitives.set_default_state = set_default_state;
|
||||||
|
|
||||||
|
rdev->r600_blit.ring_size_common = 40; /* shaders + def state */
|
||||||
|
rdev->r600_blit.ring_size_common += 10; /* fence emit for VB IB */
|
||||||
|
rdev->r600_blit.ring_size_common += 5; /* done copy */
|
||||||
|
rdev->r600_blit.ring_size_common += 10; /* fence emit for done copy */
|
||||||
|
|
||||||
|
rdev->r600_blit.ring_size_per_loop = 76;
|
||||||
|
/* set_render_target emits 2 extra dwords on rv6xx */
|
||||||
|
if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770)
|
||||||
|
rdev->r600_blit.ring_size_per_loop += 2;
|
||||||
|
|
||||||
|
rdev->r600_blit.max_dim = 8192;
|
||||||
|
|
||||||
/* 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)
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -608,9 +628,8 @@ static void r600_vb_ib_put(struct radeon_device *rdev)
|
||||||
radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
|
radeon_ib_free(rdev, &rdev->r600_blit.vb_ib);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: the function is very similar to evergreen_blit_create_rect, except
|
static unsigned r600_blit_create_rect(unsigned num_pages,
|
||||||
that it different predefined constants; consider commonizing */
|
int *width, int *height, int max_dim)
|
||||||
static unsigned r600_blit_create_rect(unsigned num_pages, int *width, int *height)
|
|
||||||
{
|
{
|
||||||
unsigned max_pages;
|
unsigned max_pages;
|
||||||
unsigned pages = num_pages;
|
unsigned pages = num_pages;
|
||||||
|
@ -628,12 +647,12 @@ static unsigned r600_blit_create_rect(unsigned num_pages, int *width, int *heigh
|
||||||
while (num_pages / rect_order) {
|
while (num_pages / rect_order) {
|
||||||
h *= 2;
|
h *= 2;
|
||||||
rect_order *= 4;
|
rect_order *= 4;
|
||||||
if (h >= MAX_RECT_DIM) {
|
if (h >= max_dim) {
|
||||||
h = MAX_RECT_DIM;
|
h = max_dim;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
max_pages = (MAX_RECT_DIM * h) / (RECT_UNIT_W * RECT_UNIT_H);
|
max_pages = (max_dim * h) / (RECT_UNIT_W * RECT_UNIT_H);
|
||||||
if (pages > max_pages)
|
if (pages > max_pages)
|
||||||
pages = max_pages;
|
pages = max_pages;
|
||||||
w = (pages * RECT_UNIT_W * RECT_UNIT_H) / h;
|
w = (pages * RECT_UNIT_W * RECT_UNIT_H) / h;
|
||||||
|
@ -659,36 +678,29 @@ int r600_blit_prepare_copy(struct radeon_device *rdev, unsigned num_pages)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
int ring_size;
|
int ring_size;
|
||||||
/* loops of emits 64 + fence emit possible */
|
int num_loops = 0;
|
||||||
int dwords_per_loop = 76, num_loops = 0;
|
int dwords_per_loop = rdev->r600_blit.ring_size_per_loop;
|
||||||
|
|
||||||
r = r600_vb_ib_get(rdev);
|
r = r600_vb_ib_get(rdev);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
/* set_render_target emits 2 extra dwords on rv6xx */
|
|
||||||
if (rdev->family > CHIP_R600 && rdev->family < CHIP_RV770)
|
|
||||||
dwords_per_loop += 2;
|
|
||||||
|
|
||||||
/* num loops */
|
/* num loops */
|
||||||
while (num_pages) {
|
while (num_pages) {
|
||||||
num_pages -= r600_blit_create_rect(num_pages, NULL, NULL);
|
num_pages -= r600_blit_create_rect(num_pages, NULL, NULL,
|
||||||
|
rdev->r600_blit.max_dim);
|
||||||
num_loops++;
|
num_loops++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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 */
|
ring_size += rdev->r600_blit.ring_size_common;
|
||||||
ring_size += 40; /* shaders + def state */
|
|
||||||
ring_size += 10; /* fence emit for VB IB */
|
|
||||||
ring_size += 5; /* done copy */
|
|
||||||
ring_size += 10; /* fence emit for done copy */
|
|
||||||
r = radeon_ring_lock(rdev, ring_size);
|
r = radeon_ring_lock(rdev, ring_size);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
set_default_state(rdev); /* 14 */
|
rdev->r600_blit.primitives.set_default_state(rdev);
|
||||||
set_shaders(rdev); /* 26 */
|
rdev->r600_blit.primitives.set_shaders(rdev);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,14 +724,17 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
|
||||||
u64 vb_gpu_addr;
|
u64 vb_gpu_addr;
|
||||||
u32 *vb;
|
u32 *vb;
|
||||||
|
|
||||||
DRM_DEBUG("emitting copy %16llx %16llx %d %d\n", src_gpu_addr, dst_gpu_addr,
|
DRM_DEBUG("emitting copy %16llx %16llx %d %d\n",
|
||||||
|
src_gpu_addr, dst_gpu_addr,
|
||||||
num_pages, rdev->r600_blit.vb_used);
|
num_pages, rdev->r600_blit.vb_used);
|
||||||
vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
|
vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used);
|
||||||
|
|
||||||
while (num_pages) {
|
while (num_pages) {
|
||||||
int w, h;
|
int w, h;
|
||||||
unsigned size_in_bytes;
|
unsigned size_in_bytes;
|
||||||
unsigned pages_per_loop = r600_blit_create_rect(num_pages, &w, &h);
|
unsigned pages_per_loop =
|
||||||
|
r600_blit_create_rect(num_pages, &w, &h,
|
||||||
|
rdev->r600_blit.max_dim);
|
||||||
|
|
||||||
size_in_bytes = pages_per_loop * RADEON_GPU_PAGE_SIZE;
|
size_in_bytes = pages_per_loop * RADEON_GPU_PAGE_SIZE;
|
||||||
DRM_DEBUG("rectangle w=%d h=%d\n", w, h);
|
DRM_DEBUG("rectangle w=%d h=%d\n", w, h);
|
||||||
|
@ -743,32 +758,21 @@ void r600_kms_blit_copy(struct radeon_device *rdev,
|
||||||
vb[10] = i2f(w);
|
vb[10] = i2f(w);
|
||||||
vb[11] = i2f(h);
|
vb[11] = i2f(h);
|
||||||
|
|
||||||
/* src 9 */
|
rdev->r600_blit.primitives.set_tex_resource(rdev, FMT_8_8_8_8,
|
||||||
set_tex_resource(rdev, FMT_8_8_8_8, w, h, w, src_gpu_addr);
|
w, h, w, src_gpu_addr);
|
||||||
|
rdev->r600_blit.primitives.cp_set_surface_sync(rdev,
|
||||||
/* 5 */
|
PACKET3_TC_ACTION_ENA,
|
||||||
cp_set_surface_sync(rdev,
|
size_in_bytes, src_gpu_addr);
|
||||||
PACKET3_TC_ACTION_ENA, size_in_bytes, src_gpu_addr);
|
rdev->r600_blit.primitives.set_render_target(rdev, COLOR_8_8_8_8,
|
||||||
|
w, h, dst_gpu_addr);
|
||||||
/* dst 23 */
|
rdev->r600_blit.primitives.set_scissors(rdev, 0, 0, w, h);
|
||||||
set_render_target(rdev, COLOR_8_8_8_8, w, h, dst_gpu_addr);
|
|
||||||
|
|
||||||
/* scissors 12 */
|
|
||||||
set_scissors(rdev, 0, 0, w, h);
|
|
||||||
|
|
||||||
/* Vertex buffer setup 14 */
|
|
||||||
vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used;
|
vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used;
|
||||||
set_vtx_resource(rdev, vb_gpu_addr);
|
rdev->r600_blit.primitives.set_vtx_resource(rdev, vb_gpu_addr);
|
||||||
|
rdev->r600_blit.primitives.draw_auto(rdev);
|
||||||
/* draw 10 */
|
rdev->r600_blit.primitives.cp_set_surface_sync(rdev,
|
||||||
draw_auto(rdev);
|
|
||||||
|
|
||||||
/* 5 */
|
|
||||||
cp_set_surface_sync(rdev,
|
|
||||||
PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA,
|
PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA,
|
||||||
size_in_bytes, dst_gpu_addr);
|
size_in_bytes, dst_gpu_addr);
|
||||||
|
|
||||||
/* 78 ring dwords per loop */
|
|
||||||
vb += 12;
|
vb += 12;
|
||||||
rdev->r600_blit.vb_used += 4*12;
|
rdev->r600_blit.vb_used += 4*12;
|
||||||
src_gpu_addr += size_in_bytes;
|
src_gpu_addr += size_in_bytes;
|
||||||
|
|
|
@ -522,9 +522,30 @@ struct r600_ih {
|
||||||
bool enabled;
|
bool enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct r600_blit_cp_primitives {
|
||||||
|
void (*set_render_target)(struct radeon_device *rdev, int format,
|
||||||
|
int w, int h, u64 gpu_addr);
|
||||||
|
void (*cp_set_surface_sync)(struct radeon_device *rdev,
|
||||||
|
u32 sync_type, u32 size,
|
||||||
|
u64 mc_addr);
|
||||||
|
void (*set_shaders)(struct radeon_device *rdev);
|
||||||
|
void (*set_vtx_resource)(struct radeon_device *rdev, u64 gpu_addr);
|
||||||
|
void (*set_tex_resource)(struct radeon_device *rdev,
|
||||||
|
int format, int w, int h, int pitch,
|
||||||
|
u64 gpu_addr);
|
||||||
|
void (*set_scissors)(struct radeon_device *rdev, int x1, int y1,
|
||||||
|
int x2, int y2);
|
||||||
|
void (*draw_auto)(struct radeon_device *rdev);
|
||||||
|
void (*set_default_state)(struct radeon_device *rdev);
|
||||||
|
};
|
||||||
|
|
||||||
struct r600_blit {
|
struct r600_blit {
|
||||||
struct mutex mutex;
|
struct mutex mutex;
|
||||||
struct radeon_bo *shader_obj;
|
struct radeon_bo *shader_obj;
|
||||||
|
struct r600_blit_cp_primitives primitives;
|
||||||
|
int max_dim;
|
||||||
|
int ring_size_common;
|
||||||
|
int ring_size_per_loop;
|
||||||
u64 shader_gpu_addr;
|
u64 shader_gpu_addr;
|
||||||
u32 vs_offset, ps_offset;
|
u32 vs_offset, ps_offset;
|
||||||
u32 state_offset;
|
u32 state_offset;
|
||||||
|
|
Loading…
Reference in a new issue