Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8eec9d6f authored by Ilija Hadzic's avatar Ilija Hadzic Committed by Dave Airlie
Browse files

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: default avatarIlija Hadzic <ihadzic@research.bell-labs.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 638dd7db
Loading
Loading
Loading
Loading
+49 −45
Original line number Original line Diff line number Diff line
@@ -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;
+21 −0
Original line number Original line Diff line number Diff line
@@ -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;