· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.DIRECTX.OPENGL —› Альфа блиттер для DDraw

Посл.отвђт Сообщенiе


Дата: Ноя 5, 2004 02:51:03

Возможно, эта тема поднималась здесь уже раз сто, но я что-то не нашел...

Кде взять или кто может запостить реально оптимизированный (быстрее уже никак) SUBJ для R5G6B5 цвета и отдельно хранящейся маски (в любом удобном формате)?

Я искал исходники и кое-что нашел, но это далеко не оптимальные варианты, а некоторые откровенно примитивны (во всех отнощениях).

Я пробовал писать свой на MMX, но опыта пока маловато и возникли некоторые вопросы: почему чтение / запись системной памяти работают так медленно (4 movq работают в 3 раза медленнее 27 математических и / или логических инструкций) и можно ли как-нибудь убыстрить их. И можно ли пока читаются следующие пиксели обрабатывать математикой предыидущие, что ли?

Система, на всякий случай AMD-K6-2-500, 256 MB SDRAM.

Такой же вопрос я запостил в общие вопросы на всякий случай...


Дата: Ноя 5, 2004 08:30:50

Вот мои, сильно не оптимизированы
на www.win32asmcommunity.net на верно есть по лучше
blit32:
	mov	eax,[fwidth]
	shl	eax,2
	mov	edx,[fheight]
	sub	[lockrc.Pitch],eax
.line:	mov	ecx,[fwidth]
	rep	movsd
	add	edi,[lockrc.Pitch]
	dec	edx
	jg	.line
	retn
;##################################################################### #####
blit16:
	mov	eax,[fwidth]
	add	eax,eax
	mov	edx,[fheight]
	sub	[lockrc.Pitch],eax
.line:	mov	ecx,[fwidth]
.pixel: mov	eax,[esi]	; red
	mov	ebx,[esi]	; green
	mov	ebp,[esi]	; blue
	shr	eax,08h
	shr	ebx,05h
	shr	ebp,03h
	and	eax,0000F800h
	and	ebx,000007E0h
	and	ebp,0000001Fh
	add	ebx,ebp
	add	eax,ebx
	stosw
	add	esi,04h
	loop	.pixel
	add	edi,[lockrc.Pitch]
	dec	edx
	jg	.line
	retn
;##################################################################### #####
blit32a:
	push	ebp
	mov	[stackp],esp

	mov	esp,$00FF00FF
	mov	ebp,$0000FF00
	sub	edi,4

	mov	eax,[fwidth]
	shl	eax,2
	mov	edx,[fheight]
	sub	[lockrc.Pitch],eax
	mov	[y],edx

.line:	mov	eax,[fwidth]
	mov	[x],eax
.pixel: movzx	edx,byte [esi+03h]	; A---          u
	mov	eax,[esi]		; -R-B           v
	mov	ecx,[esi]		; --G-          u
	and	eax,esp 		;                v
	and	ecx,ebp 		;               u
	imul	eax,edx 		;                v
	imul	ecx,edx 		;               u
	and	eax,$FF00FF00		;                u
	and	ecx,$00FF0000		;               u
	add	edi,4			;                v
	add	ecx,eax 		;               u
	xor	edx,$FF 		;                v

	mov	eax,[edi]		;               u
	mov	ebx,[edi]		;                v
	and	eax,esp 		; -R-B          u
	and	ebx,ebp 		; --G-           v
	imul	eax,edx 		;               u
	imul	ebx,edx 		;                v
	and	eax,$FF00FF00		;               u
	and	ebx,$00FF0000		;                v
	add	eax,ecx 		;               u
	add	esi,4			;                v
	add	eax,ebx 		;               u
	shr	eax,8			;               u

	dec	[x]			;                v
	mov	[edi],eax		;               u
	jg	.pixel
	add	edi,[lockrc.Pitch]
	dec	[y]
	jg	.line

	mov	esp,[stackp]
	pop	ebp
	retn
;##################################################################### #####
blit32ammx:
	push	ebp

	sub	edi,08h

	mov	eax,[fwidth]
	shl	eax,2
	mov	edx,[fheight]
	sub	[lockrc.Pitch],eax

.line:	mov	eax,[fwidth]
  .x:	add	edi,08h
	movq	mm6,[esi]
	movq	mm0,mm6 		; alpha0
	movq	mm3,mm6 		; alpha1
	pxor	mm1,mm1 		; src0
	pxor	mm4,mm4 		; src1
	pxor	mm2,mm2 		; dest0
	pxor	mm5,mm5 		; dest1
	pshufw	mm0,mm0,01010101b	; spread alpha0
	pshufw	mm3,mm3,11111111b	; spread alpha1
      punpcklbw mm1,mm6 		; unpack src0
      punpckhbw mm4,mm6 		; unpack src1
      punpcklbw mm2,[edi]		; unpack dest0
      punpckhbw mm5,[edi]		; unpack dest1
	pand	mm0,[mmx_mulmask]	; isolate alpha0
	pand	mm3,[mmx_mulmask]	; isolate alpha1
	pand	mm1,[mmx_rgbmask]	; isolate src0
	pand	mm4,[mmx_rgbmask]	; isolate src1
	pand	mm2,[mmx_rgbmask]	; isolate dest0
	pand	mm5,[mmx_rgbmask]	; isolate dest1
	pmulhuw mm1,mm0 		; src0*alpha0
	pmulhuw mm4,mm3 		; src1*alpha1
	pxor	mm0,[mmx_mulmask]	; reverse alpha0
	pxor	mm3,[mmx_mulmask]	; reverse alpha1
	pmulhuw mm2,mm0 		; dest0*alpha0
	pmulhuw mm5,mm3 		; dest1*alpha1
	paddw	mm1,mm2 		; src0+dest0
	paddw	mm4,mm5 		; src1+dest1
	psrlw	mm1,8			; truncate res0
	psrlw	mm4,8			; truncate res1
       packuswb mm1,mm4 		; res0+res1
	add	esi,08h
	sub	eax,02h
	movq	[edi],mm1
	jg	.x
	dec	edx
	jg	.line

	emms
	pop	ebp
	retn
;##################################################################### #####
blit16a:
	push	ebp
	mov	[stackp],esp

	sub	edi,2

	mov	eax,[fwidth]
	add	eax,eax
	mov	edx,[fheight]
	sub	[lockrc.Pitch],eax
	mov	[y],edx

.line:	mov	eax,[fwidth]
	mov	[x],eax
.pixel: movzx	edx,byte [esi+03h]	; A---          u
	mov	eax,[esi]		; -R-B
	mov	ecx,[esi]		; --G-
	and	eax,$00FF00FF
	and	ecx,$0000FF00
	imul	eax,edx
	imul	ecx,edx
	mov	ebx,eax
	shr	ecx,13
	shr	eax,11
	shr	ebx,16
	and	ecx,$07E0
	and	eax,$001F
	and	ebx,$F800
	xor	edx,$FF
	add	ecx,eax
	add	edi,2
	add	ecx,ebx

	shr	edx,2

	movzx	eax,word [edi]		; -R-B
	movzx	ebx,word [edi]		; --G-
	and	eax,$F81F
	and	ebx,$07E0
	imul	eax,edx
	imul	ebx,edx
	and	eax,$F81F shl 6
	and	ebx,$07E0 shl 6
	add	eax,ebx
	add	esi,4
	shr	eax,6
	add	eax,ecx

	dec	[x]
	mov	[edi],ax
	jg	.pixel
	add	edi,[lockrc.Pitch]
	dec	[y]
	jg	.line

	mov	esp,[stackp]
	pop	ebp
	retn


Дата: Ноя 5, 2004 08:33:15

забыл
mmx_rgbmask	dq	$0000FF00FF00FF00
mmx_mulmask	dq	$FF00FF00FF00FF00

fwidth = ширина
fheight = высота
lockrc.Pitch = scanline (width * bytes_per_pixel)


почему code таги на этом борде используют variable-width font? нужно fixed-width font, типа courier new (или лучше <pre> </pre>)


Дата: Ноя 7, 2004 15:13:08

AMD-K6-2 говоришь?

а ты вообще не замечал что простая запись в память там медленнее чем чтение?
дело в том что когда ты что нибудь пытаешься скэшировать, а строк в кэше нету(все модифицированы) то по вине девелоперов камня инструкция ждет сперва сохранения ячейки а потом загрузки. то есть ожидание вдвое больше что и вызывает остановку конвейера. попробуй юзать prefetchw задолго до обращения к предвыбираемой памяти.


Дата: Ноя 7, 2004 15:55:13

Вроде как раз на на AMD-K6-2 и появилась MOVNTQ - запись в память минуя кэшь ?


Дата: Ноя 7, 2004 18:56:39

вроде бы на Р3 как раз. а на К6-2 prefetch и prefetchw


Дата: Ноя 7, 2004 18:59:19

если тебе надо запись в память поставь PWT+WC для страниц буфера. тогда строка кэша оказывается записаной сразу. но тогда трабла - WC ставится через MTRR а их всего 2 там.
один под оперативку другой под видеоадаптерную память.


Дата: Ноя 9, 2004 01:14:42

2 Comrade: спасибо, но я свой на MMX написал и он лучше работает.

2 Narkomanius: насчет последнего поста - ничего не понял... :)

2 All: мне бы такой, чтобы он либо на всех процессорах работал, либо на P3, P4, AthlonXP, а не только на AMD-K6-2-500 - это уже антиквариат. :)

Вообще, не пойму, как сделан такой быстрый блиттер, например, в Ricochet Extreme / Lost Worlds, ну или ещё много игр могу привести в пример. Ведь там все 100% софтварное на DDraw'e сделано. Понимаю, там использовали Dirty Rectangles, чтобы не весь кадр перерисовывать, ну и анимация там 10 - 20 раз в секунду в основном для всех спрайтов, но все равно быстрее моего работает раз в сто.

Вообще, если кому надо, могу запостить свой код...


Дата: Ноя 11, 2004 03:31:51

В общем, все понятно... Производители памяти обещают гигабайты, а я с трудом могу переслать 64 (ш) х 64 (в) х 2 (16 бпп) х 4 (сурс, альфа и два раза бэк) х 12 (штук) х 30 (фпс) = 11,25 МБайт / сек. Да?


Дата: Ноя 11, 2004 06:16:29

На athlon@266MHz FSB за секунду можно скопировать 900Mb.
Причём эта цифра от частоты ядра почти не зависит.


Дата: Ноя 11, 2004 10:04:56 · Поправил: Narkomanius

WC- write combining, задержка данных во внутренних буферах для лучшей утилизации шины. тогда запись имеет больше шансов идти 8байтными блоками а не так как пишет прога - 1,2,4 байта. просто байты попадающие в одну восьмерку комбинированно записываются за одно обращение(2 цикла шины на К6-2 без #HOLD #WT)
PTW pagewritethrough -сквозная запись, когда данные записанные в кэш, сразу же помещаются в буфер записи. при write-back режиме буфер записи не заполняется, и запись идет по мере вытеснения строк из кэша.
то есть когда тебе захочется прочесть что нибудь в кэш, окажется что сперва надо произвести запись, что ведет к росту латентности и остановке планировщика. Данным синдромом страдают все АМДшные процы, у интеловских Write-backа _НЕТУ_. даже если они пишут что есть. у них просто сквозная запись отложенная получается.

чем PWT крут? тем что записав в строку кэша, ты можешь не беспокоиться о том что когда надо будет её вытеснить она будет можифицирована. такие строки немодифицированы по определению, и просто затираются.
WC - не нужен если ты будешь производить запись кусками по 8 байт. запись будет неконвейеризована! но потери в скорости будут меньше.

Надеюсь я ответил на твой вопрос, почему ты на своем К6-2 получил такое низкое быстродействие записи?


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.071