From b6bf652bb7c63a3849860b95739edc71f0303c57 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Wed, 20 Jul 2011 11:24:01 +0000 Subject: [PATCH] atikms: RC11.2 video blitter git-svn-id: svn://kolibrios.org@2007 a494cfbc-eb01-0410-851d-a64ba20cac60 --- drivers/ddk/core.S | 7 + drivers/video/drm/radeon/r600_blit_kms.c | 129 +++++++++++++++++++ drivers/video/drm/radeon/radeon.h | 1 + drivers/video/drm/radeon/radeon_asic.c | 4 + drivers/video/drm/radeon/radeon_benchmark.c | 16 ++- drivers/video/drm/radeon/radeon_device.c | 18 +++ drivers/video/drm/radeon/radeon_irq_kms.c | 2 +- drivers/video/drm/radeon/radeon_object_kos.c | 42 ++++++ 8 files changed, 212 insertions(+), 7 deletions(-) diff --git a/drivers/ddk/core.S b/drivers/ddk/core.S index 8f4a11bbe9..4e68712a90 100644 --- a/drivers/ddk/core.S +++ b/drivers/ddk/core.S @@ -51,6 +51,8 @@ .global _SetScreen .global _SysMsgBoardStr + .global _UserAlloc + .global _WaitEvent @@ -101,6 +103,8 @@ .def _SetKeyboardData; .scl 2; .type 32; .endef .def _SysMsgBoardStr; .scl 2; .type 32; .endef + .def _UserAlloc; .scl 2; .type 32; .endef + .def _WaitEvent; .scl 2; .type 32; .endef @@ -153,6 +157,7 @@ _SetKeyboardData: _SetScreen: _SysMsgBoardStr: +_UserAlloc: _WaitEvent: ret @@ -209,5 +214,7 @@ _WaitEvent: .ascii " -export:SetScreen" # stdcall .ascii " -export:SysMsgBoardStr" # stdcall + .ascii " -export:UserAlloc" # stdcall + .ascii " -export:WaitEvent" # stdcall diff --git a/drivers/video/drm/radeon/r600_blit_kms.c b/drivers/video/drm/radeon/r600_blit_kms.c index 69a3f096b9..cd3e8b7df7 100644 --- a/drivers/video/drm/radeon/r600_blit_kms.c +++ b/drivers/video/drm/radeon/r600_blit_kms.c @@ -843,3 +843,132 @@ void r600_kms_blit_copy(struct radeon_device *rdev, } } + +void r600_kms_video_blit(struct radeon_device *rdev, + u64 src_gpu_addr, int dstx, int dsty, int w, int h, int pitch) +{ + u64 vb_gpu_addr; + u32 *vb; + + DRM_DEBUG("emitting video copy\n"); + vb = (u32 *)(rdev->r600_blit.vb_ib->ptr + rdev->r600_blit.vb_used); + + if ((rdev->r600_blit.vb_used + 48) > rdev->r600_blit.vb_total) { + // WARN_ON(1); + } + + vb[0] = i2f(dstx); + vb[1] = i2f(dsty); + vb[2] = 0; + vb[3] = 0; + + vb[4] = i2f(dstx); + vb[5] = i2f(dsty+h); + vb[6] = 0; + vb[7] = i2f(h); + + vb[8] = i2f(dstx + w); + vb[9] = i2f(dsty + h); + vb[10] = i2f(w); + vb[11] = i2f(h); + + /* src 9 */ + set_tex_resource(rdev, FMT_8_8_8_8, + w, h, pitch/4, src_gpu_addr); + /* 5 */ + cp_set_surface_sync(rdev, + PACKET3_TC_ACTION_ENA, pitch * h, src_gpu_addr); + + /* dst 23 */ + set_render_target(rdev, COLOR_8_8_8_8, + 1024, 768, rdev->mc.vram_start); + + /* scissors 12 */ + set_scissors(rdev, 0, 0, 1024, 768); + + /* Vertex buffer setup 14 */ + vb_gpu_addr = rdev->r600_blit.vb_ib->gpu_addr + rdev->r600_blit.vb_used; + set_vtx_resource(rdev, vb_gpu_addr); + + /* draw 10 */ + draw_auto(rdev); + + /* 5 */ + cp_set_surface_sync(rdev, + PACKET3_CB_ACTION_ENA | PACKET3_CB0_DEST_BASE_ENA, + 1024*4*768, rdev->mc.vram_start); + + /* 78 ring dwords per loop */ + vb += 12; + rdev->r600_blit.vb_used += 12 * 4; + +} + +extern struct radeon_device *main_device; + +int r600_video_blit(uint64_t src_offset, int x, int y, + int w, int h, int pitch) +{ + int r; + struct radeon_device *rdev = main_device; + + mutex_lock(&rdev->r600_blit.mutex); + rdev->r600_blit.vb_ib = NULL; + r = r600_blit_prepare_copy(rdev, h*pitch); + if (r) { +// if (rdev->r600_blit.vb_ib) +// radeon_ib_free(rdev, &rdev->r600_blit.vb_ib); + mutex_unlock(&rdev->r600_blit.mutex); + return r; + } + + + r600_kms_video_blit(rdev, src_offset,x,y,w,h,pitch); + r600_blit_done_copy(rdev, NULL); + mutex_unlock(&rdev->r600_blit.mutex); +}; + +int r600_create_video(int w, int h, u32_t *outp) +{ + int r; + struct radeon_device *rdev = main_device; + struct radeon_bo *sobj = NULL; + uint64_t saddr; + void *uaddr; + + size_t size; + size_t pitch; + + pitch = radeon_align_pitch(rdev, w, 32, false) * 4; + + size = pitch * h; + r = radeon_bo_create(rdev, size, PAGE_SIZE, true, + RADEON_GEM_DOMAIN_GTT, &sobj); + if (r) { + goto fail; + } + r = radeon_bo_reserve(sobj, false); + if (unlikely(r != 0)) + goto fail; + r = radeon_bo_pin(sobj, RADEON_GEM_DOMAIN_GTT, &saddr); +// radeon_bo_unreserve(sobj); + if (r) { + goto fail; + } + + r = radeon_bo_user_map(sobj, &uaddr); + if (r) { + goto fail; + } + + ((uint64_t*)outp)[0] = saddr; + outp[2] = uaddr; + outp[3] = pitch; + + dbgprintf("Create video surface %x, mapped at %x pitch %d\n", + (uint32_t)saddr, uaddr, pitch); + return 0; + +fail: + return -1; +}; diff --git a/drivers/video/drm/radeon/radeon.h b/drivers/video/drm/radeon/radeon.h index ed7c0c9f92..1da24645d5 100644 --- a/drivers/video/drm/radeon/radeon.h +++ b/drivers/video/drm/radeon/radeon.h @@ -340,6 +340,7 @@ struct radeon_bo { struct ttm_bo_kmap_obj kmap; unsigned pin_count; void *kptr; + void *uptr; u32 cpu_addr; u32 tiling_flags; u32 pitch; diff --git a/drivers/video/drm/radeon/radeon_asic.c b/drivers/video/drm/radeon/radeon_asic.c index 23a98729b0..3412a781d9 100644 --- a/drivers/video/drm/radeon/radeon_asic.c +++ b/drivers/video/drm/radeon/radeon_asic.c @@ -165,6 +165,7 @@ static struct radeon_asic r100_asic = { .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, .ioctl_wait_idle = NULL, + .gui_idle = &r100_gui_idle, }; static struct radeon_asic r200_asic = { @@ -203,6 +204,7 @@ static struct radeon_asic r200_asic = { .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, .ioctl_wait_idle = NULL, + .gui_idle = &r100_gui_idle, }; static struct radeon_asic r300_asic = { @@ -241,6 +243,7 @@ static struct radeon_asic r300_asic = { .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, .ioctl_wait_idle = NULL, + .gui_idle = &r100_gui_idle, }; static struct radeon_asic r300_asic_pcie = { @@ -278,6 +281,7 @@ static struct radeon_asic r300_asic_pcie = { .hpd_sense = &r100_hpd_sense, .hpd_set_polarity = &r100_hpd_set_polarity, .ioctl_wait_idle = NULL, + .gui_idle = &r100_gui_idle, }; static struct radeon_asic r420_asic = { diff --git a/drivers/video/drm/radeon/radeon_benchmark.c b/drivers/video/drm/radeon/radeon_benchmark.c index d92582e695..27ac83edfc 100644 --- a/drivers/video/drm/radeon/radeon_benchmark.c +++ b/drivers/video/drm/radeon/radeon_benchmark.c @@ -48,7 +48,7 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, ENTER(); size = bsize; - n = 2; //1024; + n = 4; //1024; dbgprintf("source domain %x\n", sdomain); @@ -99,12 +99,14 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, if (r) { goto out_cleanup; } + } + r = radeon_fence_wait(fence, false); if (r) { goto out_cleanup; } radeon_fence_unref(&fence); - } + end_jiffies = GetTimerTicks(); time = end_jiffies - start_jiffies; time = jiffies_to_msecs(time); @@ -128,12 +130,14 @@ void radeon_benchmark_move(struct radeon_device *rdev, unsigned bsize, if (r) { goto out_cleanup; } + } + r = radeon_fence_wait(fence, false); if (r) { goto out_cleanup; } radeon_fence_unref(&fence); - } + end_jiffies = GetTimerTicks(); time = end_jiffies - start_jiffies; time = jiffies_to_msecs(time); @@ -176,10 +180,10 @@ out_cleanup: void radeon_benchmark(struct radeon_device *rdev) { - radeon_benchmark_move(rdev, 8192*4096, RADEON_GEM_DOMAIN_GTT, + radeon_benchmark_move(rdev, 4096*4096, RADEON_GEM_DOMAIN_GTT, RADEON_GEM_DOMAIN_VRAM); - radeon_benchmark_move(rdev, 8192*4096, RADEON_GEM_DOMAIN_VRAM, + radeon_benchmark_move(rdev, 4096*4096, RADEON_GEM_DOMAIN_VRAM, RADEON_GEM_DOMAIN_GTT); - radeon_benchmark_move(rdev, 8192*4096, RADEON_GEM_DOMAIN_VRAM, + radeon_benchmark_move(rdev, 4096*4096, RADEON_GEM_DOMAIN_VRAM, RADEON_GEM_DOMAIN_VRAM); } diff --git a/drivers/video/drm/radeon/radeon_device.c b/drivers/video/drm/radeon/radeon_device.c index 8398bd8119..d7c6da459f 100644 --- a/drivers/video/drm/radeon/radeon_device.c +++ b/drivers/video/drm/radeon/radeon_device.c @@ -974,6 +974,12 @@ static struct pci_device_id pciidlist[] = { #define SRV_ENUM_MODES 1 #define SRV_SET_MODE 2 +#define SRV_CREATE_VIDEO 9 +#define SRV_BLIT_VIDEO 10 + +int r600_video_blit(uint64_t src_offset, int x, int y, + int w, int h, int pitch); + int _stdcall display_handler(ioctl_t *io) { int retval = -1; @@ -1016,6 +1022,18 @@ int _stdcall display_handler(ioctl_t *io) retval = set_user_mode((videomode_t*)inp); }; break; + + case SRV_CREATE_VIDEO: + retval = r600_create_video(inp[0], inp[1], outp); + break; + + case SRV_BLIT_VIDEO: + r600_video_blit( ((uint64_t*)inp)[0], inp[2], inp[3], + inp[4], inp[5], inp[6]); + + retval = 0; + break; + }; return retval; diff --git a/drivers/video/drm/radeon/radeon_irq_kms.c b/drivers/video/drm/radeon/radeon_irq_kms.c index 80e7e7301e..9a87383a99 100644 --- a/drivers/video/drm/radeon/radeon_irq_kms.c +++ b/drivers/video/drm/radeon/radeon_irq_kms.c @@ -32,7 +32,7 @@ #include "radeon.h" #include "atom.h" -static struct radeon_device *main_device; +struct radeon_device *main_device; #if 0 diff --git a/drivers/video/drm/radeon/radeon_object_kos.c b/drivers/video/drm/radeon/radeon_object_kos.c index c1269b4c79..4440f3b609 100644 --- a/drivers/video/drm/radeon/radeon_object_kos.c +++ b/drivers/video/drm/radeon/radeon_object_kos.c @@ -294,6 +294,48 @@ int radeon_bo_kmap(struct radeon_bo *bo, void **ptr) return 0; } +int radeon_bo_user_map(struct radeon_bo *bo, void **ptr) +{ + bool is_iomem; + + if (bo->uptr) { + if (ptr) { + *ptr = bo->uptr; + } + return 0; + } + + if(bo->domain & RADEON_GEM_DOMAIN_VRAM) + { + return -1; + } + else + { + bo->uptr = UserAlloc(bo->tbo.num_pages << PAGE_SHIFT); + if(bo->uptr) + { + u32_t *src, *dst; + int count; + src = &((u32_t*)page_tabs)[(u32_t)bo->kptr >> 12]; + dst = &((u32_t*)page_tabs)[(u32_t)bo->uptr >> 12]; + count = bo->tbo.num_pages; + + while(count--) + { + *dst++ = (0xFFFFF000 & *src++) | 0x207 ; // map as shared page + }; + } + else + return -1; + } + + if (ptr) { + *ptr = bo->uptr; + } + + return 0; +} + void radeon_bo_kunmap(struct radeon_bo *bo) { if (bo->kptr == NULL)