15,7 → 15,6 |
|
#include <syscall.h> |
|
#include "hmm.h" |
#include "bitmap.h" |
|
extern struct drm_device *main_device; |
693,12 → 692,13 |
|
GetWindowRect(&winrc); |
{ |
static warn_count; |
// static warn_count; |
|
mask->width = winrc.right - winrc.left + 1; |
mask->height = winrc.bottom - winrc.top + 1; |
mask->bo_pitch = (mask->width+15) & ~15; |
|
#if 0 |
if(warn_count < 1) |
{ |
printf("left %d top %d right %d bottom %d\n", |
706,6 → 706,8 |
printf("mask pitch %d data %p\n", mask->bo_pitch, mask->bo_size); |
warn_count++; |
}; |
#endif |
|
}; |
|
|
828,700 → 830,6 |
|
|
|
#ifdef __HWA__ |
|
extern struct hmm bm_mm; |
|
|
typedef struct |
{ |
int left; |
int top; |
int right; |
int bottom; |
}rect_t; |
|
|
#include "clip.inc" |
|
void FASTCALL GetWindowRect(rect_t *rc)__asm__("GetWindowRect"); |
|
#define CURRENT_TASK (0x80003000) |
|
static u32_t get_display_map() |
{ |
u32_t addr; |
|
addr = (u32_t)os_display; |
addr+= sizeof(display_t); /* shoot me */ |
return *(u32_t*)addr; |
} |
|
#define XY_COLOR_BLT ((2<<29)|(0x50<<22)|(0x4)) |
#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) |
#define XY_SRC_COPY_CHROMA_CMD ((2<<29)|(0x73<<22)|8) |
#define ROP_COPY_SRC 0xCC |
#define FORMAT8888 3 |
|
#define BLT_WRITE_ALPHA (1<<21) |
#define BLT_WRITE_RGB (1<<20) |
|
|
|
typedef int v4si __attribute__ ((vector_size (16))); |
|
|
|
static void |
i915_gem_execbuffer_retire_commands(struct drm_device *dev, |
struct drm_file *file, |
struct intel_ring_buffer *ring) |
{ |
/* Unconditionally force add_request to emit a full flush. */ |
ring->gpu_caches_dirty = true; |
|
/* Add a breadcrumb for the completion of the batch buffer */ |
(void)i915_add_request(ring, file, NULL); |
} |
|
int srv_blit_bitmap(u32 hbitmap, int dst_x, int dst_y, |
int src_x, int src_y, u32 w, u32 h) |
{ |
drm_i915_private_t *dev_priv = main_device->dev_private; |
struct intel_ring_buffer *ring; |
struct context *context; |
|
bitmap_t *bitmap; |
rect_t winrc; |
clip_t dst_clip; |
clip_t src_clip; |
u32_t width; |
u32_t height; |
|
u32_t br13, cmd, slot_mask, *b; |
u32_t offset; |
u8 slot; |
int n=0; |
int ret; |
|
if(unlikely(hbitmap==0)) |
return -1; |
|
bitmap = (bitmap_t*)hmm_get_data(&bm_mm, hbitmap); |
|
if(unlikely(bitmap==NULL)) |
return -1; |
|
context = get_context(main_device); |
if(unlikely(context == NULL)) |
return -1; |
|
GetWindowRect(&winrc); |
{ |
static warn_count; |
|
if(warn_count < 1) |
{ |
printf("left %d top %d right %d bottom %d\n", |
winrc.left, winrc.top, winrc.right, winrc.bottom); |
printf("bitmap width %d height %d\n", w, h); |
warn_count++; |
}; |
}; |
|
|
dst_clip.xmin = 0; |
dst_clip.ymin = 0; |
dst_clip.xmax = winrc.right-winrc.left; |
dst_clip.ymax = winrc.bottom -winrc.top; |
|
src_clip.xmin = 0; |
src_clip.ymin = 0; |
src_clip.xmax = bitmap->width - 1; |
src_clip.ymax = bitmap->height - 1; |
|
width = w; |
height = h; |
|
if( blit_clip(&dst_clip, &dst_x, &dst_y, |
&src_clip, &src_x, &src_y, |
&width, &height) ) |
return 0; |
|
dst_x+= winrc.left; |
dst_y+= winrc.top; |
|
slot = *((u8*)CURRENT_TASK); |
|
slot_mask = (u32_t)slot<<24; |
|
{ |
#if 0 |
static v4si write_mask = {0xFF000000, 0xFF000000, |
0xFF000000, 0xFF000000}; |
|
u8* src_offset; |
u8* dst_offset; |
|
src_offset = (u8*)(src_y*bitmap->pitch + src_x*4); |
src_offset += (u32)bitmap->uaddr; |
|
dst_offset = (u8*)(dst_y*os_display->width + dst_x); |
dst_offset+= get_display_map(); |
|
u32_t tmp_h = height; |
|
__asm__ __volatile__ ( |
"movdqa %[write_mask], %%xmm7 \n" |
"movd %[slot_mask], %%xmm6 \n" |
"punpckldq %%xmm6, %%xmm6 \n" |
"punpcklqdq %%xmm6, %%xmm6 \n" |
:: [write_mask] "m" (write_mask), |
[slot_mask] "g" (slot_mask) |
:"xmm7", "xmm6"); |
|
while( tmp_h--) |
{ |
u32_t tmp_w = width; |
|
u8* tmp_src = src_offset; |
u8* tmp_dst = dst_offset; |
|
src_offset+= bitmap->pitch; |
dst_offset+= os_display->width; |
|
while( tmp_w >= 8 ) |
{ |
__asm__ __volatile__ ( |
"movq (%0), %%xmm0 \n" |
"punpcklbw %%xmm0, %%xmm0 \n" |
"movdqa %%xmm0, %%xmm1 \n" |
"punpcklwd %%xmm0, %%xmm0 \n" |
"punpckhwd %%xmm1, %%xmm1 \n" |
"pcmpeqb %%xmm6, %%xmm0 \n" |
"pcmpeqb %%xmm6, %%xmm1 \n" |
"maskmovdqu %%xmm7, %%xmm0 \n" |
"addl $16, %%edi \n" |
"maskmovdqu %%xmm7, %%xmm1 \n" |
:: "r" (tmp_dst), "D" (tmp_src) |
:"xmm0", "xmm1"); |
__asm__ __volatile__ ("":::"edi"); |
tmp_w -= 8; |
tmp_src += 32; |
tmp_dst += 8; |
}; |
|
if( tmp_w >= 4 ) |
{ |
__asm__ __volatile__ ( |
"movd (%0), %%xmm0 \n" |
"punpcklbw %%xmm0, %%xmm0 \n" |
"punpcklwd %%xmm0, %%xmm0 \n" |
"pcmpeqb %%xmm6, %%xmm0 \n" |
"maskmovdqu %%xmm7, %%xmm0 \n" |
:: "r" (tmp_dst), "D" (tmp_src) |
:"xmm0"); |
tmp_w -= 4; |
tmp_src += 16; |
tmp_dst += 4; |
}; |
|
while( tmp_w--) |
{ |
*(tmp_src+3) = (*tmp_dst==slot)?0xFF:0x00; |
tmp_src+=4; |
tmp_dst++; |
}; |
}; |
#else |
u8* src_offset; |
u8* dst_offset; |
u32 ifl; |
|
src_offset = (u8*)(src_y*bitmap->pitch + src_x*4); |
src_offset += (u32)bitmap->uaddr; |
|
dst_offset = (u8*)(dst_y*os_display->width + dst_x); |
dst_offset+= get_display_map(); |
|
u32_t tmp_h = height; |
|
ifl = safe_cli(); |
while( tmp_h--) |
{ |
u32_t tmp_w = width; |
|
u8* tmp_src = src_offset; |
u8* tmp_dst = dst_offset; |
|
src_offset+= bitmap->pitch; |
dst_offset+= os_display->width; |
|
while( tmp_w--) |
{ |
*(tmp_src+3) = (*tmp_dst==slot)?0xFF:0x00; |
tmp_src+=4; |
tmp_dst++; |
}; |
}; |
safe_sti(ifl); |
} |
#endif |
|
{ |
static warn_count; |
|
if(warn_count < 1) |
{ |
printf("blit width %d height %d\n", |
width, height); |
warn_count++; |
}; |
}; |
|
|
if((context->cmd_buffer & 0xFC0)==0xFC0) |
context->cmd_buffer&= 0xFFFFF000; |
|
b = (u32_t*)ALIGN(context->cmd_buffer,16); |
|
offset = context->cmd_offset + ((u32_t)b & 0xFFF); |
|
cmd = XY_SRC_COPY_CHROMA_CMD | BLT_WRITE_RGB | BLT_WRITE_ALPHA; |
cmd |= 3 << 17; |
|
br13 = os_display->pitch; |
br13|= ROP_COPY_SRC << 16; |
br13|= FORMAT8888 << 24; |
|
b[n++] = cmd; |
b[n++] = br13; |
b[n++] = (dst_y << 16) | dst_x; // left, top |
b[n++] = ((dst_y+height)<< 16)|(dst_x+width); // bottom, right |
b[n++] = 0; // destination |
b[n++] = (src_y << 16) | src_x; // source left & top |
b[n++] = bitmap->pitch; // source pitch |
b[n++] = bitmap->gaddr; // source |
|
b[n++] = 0; // Transparency Color Low |
b[n++] = 0x00FFFFFF; // Transparency Color High |
|
b[n++] = MI_BATCH_BUFFER_END; |
if( n & 1) |
b[n++] = MI_NOOP; |
|
context->cmd_buffer+= n*4; |
|
context->obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND; |
|
|
mutex_lock(&main_device->struct_mutex); |
|
i915_gem_object_set_to_gtt_domain(bitmap->obj, false); |
|
if (HAS_BLT(main_device)) |
{ |
u32 seqno; |
int i; |
|
ring = &dev_priv->ring[BCS]; |
// printf("dispatch... "); |
|
i915_gem_object_sync(bitmap->obj, ring); |
intel_ring_invalidate_all_caches(ring); |
|
seqno = i915_gem_next_request_seqno(ring); |
// printf("seqno = %d\n", seqno); |
|
for (i = 0; i < ARRAY_SIZE(ring->sync_seqno); i++) { |
if (seqno < ring->sync_seqno[i]) { |
/* The GPU can not handle its semaphore value wrapping, |
* so every billion or so execbuffers, we need to stall |
* the GPU in order to reset the counters. |
*/ |
DRM_DEBUG("wrap seqno\n"); |
|
ret = i915_gpu_idle(main_device); |
if (ret) |
goto fail; |
i915_gem_retire_requests(main_device); |
|
BUG_ON(ring->sync_seqno[i]); |
} |
} |
|
ret = ring->dispatch_execbuffer(ring, offset, n*4); |
if (ret) |
goto fail; |
// printf("done\n"); |
|
bitmap->obj->base.read_domains = bitmap->obj->base.pending_read_domains; |
bitmap->obj->base.write_domain = bitmap->obj->base.pending_write_domain; |
bitmap->obj->fenced_gpu_access = bitmap->obj->pending_fenced_gpu_access; |
|
i915_gem_object_move_to_active(bitmap->obj, ring, seqno); |
|
i915_gem_execbuffer_retire_commands(main_device, NULL, ring); |
// printf("retire\n"); |
} |
else |
{ |
ring = &dev_priv->ring[RCS]; |
ring->dispatch_execbuffer(ring, offset, n*4); |
ring->flush(ring, 0, I915_GEM_DOMAIN_RENDER); |
}; |
|
// bitmap->obj->base.read_domains = I915_GEM_DOMAIN_CPU; |
// bitmap->obj->base.write_domain = I915_GEM_DOMAIN_CPU; |
|
mutex_unlock(&main_device->struct_mutex); |
fail: |
return ret; |
}; |
|
|
#if 0 |
|
i915_gem_execbuffer_retire_commands(dev, ring); |
/* For display hotplug interrupt */ |
static void |
ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) |
{ |
if ((dev_priv->irq_mask & mask) != 0) { |
dev_priv->irq_mask &= ~mask; |
I915_WRITE(DEIMR, dev_priv->irq_mask); |
POSTING_READ(DEIMR); |
} |
} |
|
static int ironlake_enable_vblank(struct drm_device *dev, int pipe) |
{ |
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
unsigned long irqflags; |
|
// if (!i915_pipe_enabled(dev, pipe)) |
// return -EINVAL; |
|
spin_lock_irqsave(&dev_priv->irq_lock, irqflags); |
ironlake_enable_display_irq(dev_priv, (pipe == 0) ? |
DE_PIPEA_VBLANK : DE_PIPEB_VBLANK); |
spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
|
return 0; |
} |
|
|
|
static int i915_interrupt_info(struct drm_device *dev) |
{ |
drm_i915_private_t *dev_priv = dev->dev_private; |
int ret, i, pipe; |
|
if (!HAS_PCH_SPLIT(dev)) { |
dbgprintf("Interrupt enable: %08x\n", |
I915_READ(IER)); |
dbgprintf("Interrupt identity: %08x\n", |
I915_READ(IIR)); |
dbgprintf("Interrupt mask: %08x\n", |
I915_READ(IMR)); |
for_each_pipe(pipe) |
dbgprintf("Pipe %c stat: %08x\n", |
pipe_name(pipe), |
I915_READ(PIPESTAT(pipe))); |
} else { |
dbgprintf("North Display Interrupt enable: %08x\n", |
I915_READ(DEIER)); |
dbgprintf("North Display Interrupt identity: %08x\n", |
I915_READ(DEIIR)); |
dbgprintf("North Display Interrupt mask: %08x\n", |
I915_READ(DEIMR)); |
dbgprintf("South Display Interrupt enable: %08x\n", |
I915_READ(SDEIER)); |
dbgprintf("South Display Interrupt identity: %08x\n", |
I915_READ(SDEIIR)); |
dbgprintf("South Display Interrupt mask: %08x\n", |
I915_READ(SDEIMR)); |
dbgprintf("Graphics Interrupt enable: %08x\n", |
I915_READ(GTIER)); |
dbgprintf("Graphics Interrupt identity: %08x\n", |
I915_READ(GTIIR)); |
dbgprintf("Graphics Interrupt mask: %08x\n", |
I915_READ(GTIMR)); |
} |
dbgprintf("Interrupts received: %d\n", |
atomic_read(&dev_priv->irq_received)); |
for (i = 0; i < I915_NUM_RINGS; i++) { |
if (IS_GEN6(dev) || IS_GEN7(dev)) { |
printf("Graphics Interrupt mask (%s): %08x\n", |
dev_priv->ring[i].name, |
I915_READ_IMR(&dev_priv->ring[i])); |
} |
// i915_ring_seqno_info(m, &dev_priv->ring[i]); |
} |
|
return 0; |
} |
|
void execute_buffer (struct drm_i915_gem_object *buffer, uint32_t offset, |
int size) |
{ |
struct intel_ring_buffer *ring; |
drm_i915_private_t *dev_priv = main_device->dev_private; |
u32 invalidate; |
u32 seqno = 2; |
|
offset += buffer->gtt_offset; |
// dbgprintf("execute %x size %d\n", offset, size); |
|
// asm volatile( |
// "mfence \n" |
// "wbinvd \n" |
// "mfence \n" |
// :::"memory"); |
|
ring = &dev_priv->ring[RCS]; |
ring->dispatch_execbuffer(ring, offset, size); |
|
invalidate = I915_GEM_DOMAIN_COMMAND; |
if (INTEL_INFO(main_device)->gen >= 4) |
invalidate |= I915_GEM_DOMAIN_SAMPLER; |
if (ring->flush(ring, invalidate, 0)) |
i915_gem_next_request_seqno(ring); |
|
ring->irq_get(ring); |
|
ring->add_request(ring, &seqno); |
|
// i915_interrupt_info(main_device); |
|
}; |
|
|
int blit_textured(u32 hbitmap, int dst_x, int dst_y, |
int src_x, int src_y, u32 w, u32 h) |
{ |
drm_i915_private_t *dev_priv = main_device->dev_private; |
|
bitmap_t *src_bitmap, *dst_bitmap; |
bitmap_t screen; |
|
rect_t winrc; |
|
// dbgprintf(" handle: %d dx %d dy %d sx %d sy %d w %d h %d\n", |
// hbitmap, dst_x, dst_y, src_x, src_y, w, h); |
|
if(unlikely(hbitmap==0)) |
return -1; |
|
src_bitmap = (bitmap_t*)hman_get_data(&bm_man, hbitmap); |
// dbgprintf("bitmap %x\n", src_bitmap); |
|
if(unlikely(src_bitmap==NULL)) |
return -1; |
|
GetWindowRect(&winrc); |
|
screen.pitch = os_display->pitch; |
screen.gaddr = 0; |
screen.width = os_display->width; |
screen.height = os_display->height; |
screen.obj = (void*)-1; |
|
dst_bitmap = &screen; |
|
dst_x+= winrc.left; |
dst_y+= winrc.top; |
|
sna_blit_copy(dst_bitmap, dst_x, dst_y, w, h, src_bitmap, src_x, src_y); |
|
}; |
|
int sna_blit_tex(bitmap_t *dst_bitmap, int dst_x, int dst_y, |
int w, int h, bitmap_t *src_bitmap, int src_x, int src_y, |
bitmap_t *mask_bitmap); |
|
|
int blit_tex(u32 hbitmap, int dst_x, int dst_y, |
int src_x, int src_y, u32 w, u32 h) |
{ |
drm_i915_private_t *dev_priv = main_device->dev_private; |
struct context *ctx; |
|
bitmap_t *src_bitmap, *dst_bitmap; |
bitmap_t screen; |
int ret; |
|
bitmap_t *mask_bitmap; |
rect_t winrc; |
|
// dbgprintf(" handle: %d dx %d dy %d sx %d sy %d w %d h %d\n", |
// hbitmap, dst_x, dst_y, src_x, src_y, w, h); |
|
if(unlikely(hbitmap==0)) |
return -1; |
|
src_bitmap = (bitmap_t*)hman_get_data(&bm_man, hbitmap); |
// dbgprintf("bitmap %x\n", src_bitmap); |
|
if(unlikely(src_bitmap==NULL)) |
return -1; |
|
ctx = get_context(); |
if(unlikely(ctx==NULL)) |
{ |
ret = create_context(); |
if(ret!=0) |
return -1; |
|
ctx = get_context(); |
}; |
|
mask_bitmap = ctx->mask; |
|
GetWindowRect(&winrc); |
dst_x+= winrc.left; |
dst_y+= winrc.top; |
|
|
if(ctx->seqno != os_display->mask_seqno) |
{ |
u8* src_offset; |
u8* dst_offset; |
u32 slot; |
u32 ifl; |
|
ret = gem_object_lock(mask_bitmap->obj); |
if(ret !=0 ) |
{ |
dbgprintf("%s fail\n", __FUNCTION__); |
return ret; |
}; |
|
// printf("width %d height %d\n", winrc.right, winrc.bottom); |
|
mask_bitmap->width = winrc.right; |
mask_bitmap->height = winrc.bottom; |
mask_bitmap->pitch = ALIGN(w,64); |
|
slot = *((u8*)CURRENT_TASK); |
// slot = 0x01; |
|
slot|= (slot<<8)|(slot<<16)|(slot<<24); |
|
|
__asm__ __volatile__ ( |
"movd %[slot], %%xmm6 \n" |
"punpckldq %%xmm6, %%xmm6 \n" |
"punpcklqdq %%xmm6, %%xmm6 \n" |
:: [slot] "m" (slot) |
:"xmm6"); |
|
src_offset = mask_bitmap->uaddr; |
|
dst_offset = (u8*)(dst_y*os_display->width + dst_x); |
dst_offset+= get_display_map(); |
|
u32_t tmp_h = mask_bitmap->height; |
|
ifl = safe_cli(); |
while( tmp_h--) |
{ |
int tmp_w = mask_bitmap->width; |
|
u8* tmp_src = src_offset; |
u8* tmp_dst = dst_offset; |
|
src_offset+= mask_bitmap->pitch; |
dst_offset+= os_display->width; |
|
// while( tmp_w--) |
// { |
// *(tmp_src) = (*tmp_dst==slot)?0x1:0x00; |
// tmp_src++; |
// tmp_dst++; |
// }; |
while(tmp_w >= 64) |
{ |
__asm__ __volatile__ ( |
"movdqu (%0), %%xmm0 \n" |
"movdqu 16(%0), %%xmm1 \n" |
"movdqu 32(%0), %%xmm2 \n" |
"movdqu 48(%0), %%xmm3 \n" |
"pcmpeqb %%xmm6, %%xmm0 \n" |
"pcmpeqb %%xmm6, %%xmm1 \n" |
"pcmpeqb %%xmm6, %%xmm2 \n" |
"pcmpeqb %%xmm6, %%xmm3 \n" |
"movdqa %%xmm0, (%%edi) \n" |
"movdqa %%xmm1, 16(%%edi) \n" |
"movdqa %%xmm2, 32(%%edi) \n" |
"movdqa %%xmm3, 48(%%edi) \n" |
|
:: "r" (tmp_dst), "D" (tmp_src) |
:"xmm0","xmm1","xmm2","xmm3"); |
tmp_w -= 64; |
tmp_src += 64; |
tmp_dst += 64; |
} |
|
if( tmp_w >= 32 ) |
{ |
__asm__ __volatile__ ( |
"movdqu (%0), %%xmm0 \n" |
"movdqu 16(%0), %%xmm1 \n" |
"pcmpeqb %%xmm6, %%xmm0 \n" |
"pcmpeqb %%xmm6, %%xmm1 \n" |
"movdqa %%xmm0, (%%edi) \n" |
"movdqa %%xmm1, 16(%%edi) \n" |
|
:: "r" (tmp_dst), "D" (tmp_src) |
:"xmm0","xmm1"); |
tmp_w -= 32; |
tmp_src += 32; |
tmp_dst += 32; |
} |
|
while( tmp_w > 0 ) |
{ |
__asm__ __volatile__ ( |
"movdqu (%0), %%xmm0 \n" |
"pcmpeqb %%xmm6, %%xmm0 \n" |
"movdqa %%xmm0, (%%edi) \n" |
:: "r" (tmp_dst), "D" (tmp_src) |
:"xmm0"); |
tmp_w -= 16; |
tmp_src += 16; |
tmp_dst += 16; |
} |
}; |
safe_sti(ifl); |
ctx->seqno = os_display->mask_seqno; |
} |
|
screen.pitch = os_display->pitch; |
screen.gaddr = 0; |
screen.width = os_display->width; |
screen.height = os_display->height; |
screen.obj = (void*)-1; |
|
dst_bitmap = &screen; |
|
|
sna_blit_tex(dst_bitmap, dst_x, dst_y, w, h, src_bitmap, src_x, src_y, |
mask_bitmap); |
|
// asm volatile ("int3"); |
}; |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
void __stdcall run_workqueue(struct workqueue_struct *cwq) |
{ |
unsigned long irqflags; |