Здравствуйте, spbAngel, Вы писали:
A>Здравствуйте, Andrew S, Вы писали:
A>>>Думаете, стОит использовать именно DirectDraw? AS>>Нет, не стОит. Там практически не поддерживается аппаратное ускорение, даже для блиттера (по-крайней мере, я для себя в свое время такие выводы сделал, потестировав производительность блиттинга директдрава и gdi). Почти все современные 2d игрушки используют direct3d.
Видимо во времена ваших тестов самыми распространёнными картами были S3 Trio
AFAIK, DirectDraw умеет делать stretch с фильтрацией на большинстве современных и не очень видеокарт (начиная где-то с TNT).
Хотя у некоторых карт есть специфические особенности, например, у Radeon'ов (по крайней мере 9000'ой серии) размер поверхности, с которой можно делать stretch, ограничен максимальным размером текстуры (видимо, ATI'шники реализовали stretch через наложение текстуры; у NVidia всё "по-честному", размер поверхности ограничен только объёмом видеопамяти). Похожие проблемы у интегрированного видео на i915 — там при превышении макс. размера текстуры всё начинает сильно тормозить. На старом интегрированном видео (i810, i815 и вроде i845) аппаратный stretch через DirectDraw не работает, хотя текстуры накладывать они могут.
В D3D ограничение на размер текстуры официальное, т.е. больше — однозначно нельзя. Обычный макс. размер для карты "средней устарелости" (ранние GeForce, Radeon) — 2048 * 2048.
А игрушки используют D3D главным образом для спецэффектов вроде полупрозрачности, поворота картинки и т.п. Этого в DirectDraw действительно нет.
Re[3]: [GDI] Узкое место - StretchBlt. Возможна ли альтернат
NB>>в данном случае StretchBlt выполняется в памяти, GDI тут поступает чисто софтово, отсюда тормоза. видеокарта убыстряет растровые операции при переносе видеопамять-видеопамять, и, МОЖЕТ БЫТЬ, оперативка-видеопамять.
A>Не подскажите, как с этим можно использовать? Как загружать рисунки в видеопамять?
под видеопамятью в данном случае я подразумевал видеобуфер, т.е. экран, т.е. самая быстрая отрисовка — из одного видимого окна в другое видимое окно (или из одной части окна в другое)
в данном случае это не поможет
для загрузки изображений в память видеокарты (текстур, например) требуется использование DirectX
как более быструю альтернативу могу предложить использовать DirectDraw или группу функций DrawDib
Все вопросы на nightblade@inbox.ru
Re[2]: [GDI] Узкое место - StretchBlt. Возможна ли альтернат
. Хотя, по этому поводу, критически высказывались некоторые люди. Имеет ли смысл проверять? И заменить StretchBlt на DrawDibDraw?
Не имеет. Видимый прирост производительности _в_некоторых_ ситуациях обеспечивает только ручное написание блиттера. А обычно gdi даже быстрее.
Теперь, что надо делать вам.
1. Вынести создание совместимого контекста и битмапа за пределы paint — пусть живет всегда (соответственно, пересоздавать при изменении режимов, для чего обрабатывать соотв. сообщение). Попробовать — если производительнсть устроит — отлично. В большинстве нормальных драйверов тут используется аппаратный блиттер, поэтому даже написав функции стретча вручную, сравнимой производительности не достигнуть.
2. Попробовать использовать dib секции вместо совместимого битмапа, либо обычные DIB.
А вообще — 100 фпс при помощи или без gdi — довольно нетривиально. Учитывая, что один экран это по меньшей мере 4 мб данных + затраты на скалинг.. Имхо, без аппаратной поддержки тут не обойтись.
Может, direct3d посмотреть?
A>>>Насколько я помню, DirectDraw отсутствует уже в 8-ой версии DirectX. Сейчас пишу прототип на Direct3D. Или я неправ? Просто Direct3D для решения 2D-задачи... Просто непривычно.
NB>>DirectX любой версии тащит за собой все предыдущие, для совместимости
A>Думаете, стОит использовать именно DirectDraw? Понимаю, что логичней, но... Не могу сформулировать в вопрос чувства. Как-никак 7-ая версия...
Нет, не стОит. Там практически не поддерживается аппаратное ускорение, даже для блиттера (по-крайней мере, я для себя в свое время такие выводы сделал, потестировав производительность блиттинга директдрава и gdi). Почти все современные 2d игрушки используют direct3d.
Во время выполнения программы, приходится вызывать функцию StretchBlt. В среднем, около 100-120 раз в секунду. Задача алгоритма — пропорциональный scaling некоторых изображений с выводом результата на экран (в данном случае — в окно).
Оцените, pls, код. И подскажите, какие есть альтернативы. В StretchBlt не устраивает скорость и "ступенчатость" (по-моему, это называется "ближайший цвет" — отсутствие сглаживания)
HWND iHwnd;
int mCount;
int mCountOfScale;
RECT[] mDestRect;
HDC[] mSrcBitmapDC;
int[] mSrcBitmapWidth;
int[] mSrcBitmapHeight;
float mScale;
case WM_PAINT:
int lWidth = 1024;
int lHeight = 738;
PAINTSTRUCT lPS;
HDC lWindowDC = ::BeginPaint(iHwnd, &lPS);
HDC lBitmapDC = ::CreateCompatibleDC(lWindowDC);
HBITMAP lBitmap = ::CreateCompatibleBitmap(lWindowDC, lWidth, lHeight);
HGDIOBJ lNullBitmap = ::SelectObject(lBitmapDC, lBitmap);
for (int j = 0; j < mCount; j++)
{
::StretchBlt(
lBitmapDC, // dest DC - tempory image
mDestRect[j].left, mDestRect[j].top, // position for drawing
mSrcBitmapWidth[j] * ьScale, // needed width of image
mSrcBitmapHeight[j] * mScale, // needed height of image
mSrcBitmapDC[j], // src DC - image
0, 0, mSrcBitmapWidth[j], mSrcBitmapHeight[j], // size of source image
SRCCOPY);
}
::BitBlt(lWindowDC, 0, 0, lWidth, lHeight, lBitmapDC, 0, 0, SRCCOPY);
::SelectObject(lBitmapDC, lNullBitmap);
::DeleteDC(lBitmapDC);
::DeleteObject(lBitmap);
::EndPaint(iHwnd, &lPS);
break;
Примечания:
все исходные структуры для примера упрощены до массивов
копирование во временный bitmap задумано, как избавление от мерцания. Или я чего-то неправильно делаю?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
07.11.06 13:45: Перенесено модератором из 'WIN API' — Odi$$ey
Re: [GDI] Узкое место - StretchBlt. Возможна ли альтернатива
A>Оцените, pls, код. И подскажите, какие есть альтернативы. В StretchBlt не устраивает скорость и "ступенчатость" (по-моему, это называется "ближайший цвет" — отсутствие сглаживания)
SetStretchBltMode — есть такая функция. переключает режим масштабирования, сглаживание в этом списке присутствует под именем HALFTONE (только в линейке NT). тормозит еще сильнее, естественно
в данном случае StretchBlt выполняется в памяти, GDI тут поступает чисто софтово, отсюда тормоза. видеокарта убыстряет растровые операции при переносе видеопамять-видеопамять, и, МОЖЕТ БЫТЬ, оперативка-видеопамять.
а нельзя картинку отрендерить один раз, а потом показывать по WM_PAINT обычным BitBlt?
Все вопросы на nightblade@inbox.ru
Re: [GDI] Узкое место - StretchBlt. Возможна ли альтернатива
От:
Аноним
Дата:
07.11.06 10:58
Оценка:
Здравствуйте, spbAngel, Вы писали:
A>Во время выполнения программы, приходится вызывать функцию StretchBlt. В среднем, около 100-120 раз в секунду. Задача алгоритма — пропорциональный scaling некоторых изображений с выводом результата на экран (в данном случае — в окно).
SetStretchBltMode
A зачем 100-120 раз в секунду, если даже для фильма 30 раз вполне достаточно? И каждый раз именно Stretch?
Re: [GDI] Узкое место - StretchBlt. Возможна ли альтернатива
Судя по моему предыдущему опыту, подобные критические функции я просто переписывал вручную, что всегда давало серьезный прирост производительности.
Просто для стандартных RGBA использовать свою отрисовку, а для всяких "нестандартных" — _стандартную_.
Учитывая, что отрисовка чисто софтварная, то можно реализовать софтварный мип-маппинг иль еще чего наворотить, но это никому ненужный изврат, зато не будет ступенчатости .
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: [GDI] Узкое место - StretchBlt. Возможна ли альтернат
Здравствуйте, NightBlade, Вы писали:
A>>Оцените, pls, код. И подскажите, какие есть альтернативы. В StretchBlt не устраивает скорость и "ступенчатость" (по-моему, это называется "ближайший цвет" — отсутствие сглаживания)
NB>SetStretchBltMode — есть такая функция. переключает режим масштабирования, сглаживание в этом списке присутствует под именем HALFTONE (только в линейке NT). тормозит еще сильнее, естественно
Спасибо. Попробую.
NB>в данном случае StretchBlt выполняется в памяти, GDI тут поступает чисто софтово, отсюда тормоза. видеокарта убыстряет растровые операции при переносе видеопамять-видеопамять, и, МОЖЕТ БЫТЬ, оперативка-видеопамять.
Не подскажите, как с этим можно использовать? Как загружать рисунки в видеопамять?
NB>а нельзя картинку отрендерить один раз, а потом показывать по WM_PAINT обычным BitBlt?
К сожалению, нет. Исходные рисунки и конечные положения на рисунке постоянно меняются.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: [GDI] Узкое место - StretchBlt. Возможна ли альтернат
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте, spbAngel, Вы писали:
A>>Во время выполнения программы, приходится вызывать функцию StretchBlt. В среднем, около 100-120 раз в секунду. Задача алгоритма — пропорциональный scaling некоторых изображений с выводом результата на экран (в данном случае — в окно). А>SetStretchBltMode
А>A зачем 100-120 раз в секунду, если даже для фильма 30 раз вполне достаточно? И каждый раз именно Stretch?
Именно Stretch. Около 20-25 раз в секунду, около 5-10 (до 20) рисунков за раз.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re: [GDI] Узкое место - StretchBlt. Возможна ли альтернатива
Здравствуйте, Andrew S, Вы писали:
AS>Может, direct3d посмотреть?
Спасибо. На днях понял, что это вполне подходящий вариант (Direct3D для отрисовки 2D — не мог привыкнуть) и дописываю уже прототип. За одно и DirectX изучу...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: [GDI] Узкое место - StretchBlt. Возможна ли альтернат
Здравствуйте, NightBlade, Вы писали:
NB>для загрузки изображений в память видеокарты (текстур, например) требуется использование DirectX
NB>как более быструю альтернативу могу предложить использовать DirectDraw или группу функций DrawDib
Насколько я помню, DirectDraw отсутствует уже в 8-ой версии DirectX. Сейчас пишу прототип на Direct3D. Или я неправ? Просто Direct3D для решения 2D-задачи... Просто непривычно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[5]: [GDI] Узкое место - StretchBlt. Возможна ли альтернат
Здравствуйте, spbAngel, Вы писали:
A>Насколько я помню, DirectDraw отсутствует уже в 8-ой версии DirectX. Сейчас пишу прототип на Direct3D. Или я неправ? Просто Direct3D для решения 2D-задачи... Просто непривычно.
Direct3D для 2D задачи — вполне нормальное явление. Ибо так можно задействовать мощь аппаратного ускорения современных видеокарт.
Re[5]: [GDI] Узкое место - StretchBlt. Возможна ли альтернат
A>Насколько я помню, DirectDraw отсутствует уже в 8-ой версии DirectX. Сейчас пишу прототип на Direct3D. Или я неправ? Просто Direct3D для решения 2D-задачи... Просто непривычно.
DirectX любой версии тащит за собой все предыдущие, для совместимости
Все вопросы на nightblade@inbox.ru
Re[6]: [GDI] Узкое место - StretchBlt. Возможна ли альтернат
Здравствуйте, NightBlade, Вы писали:
A>>Насколько я помню, DirectDraw отсутствует уже в 8-ой версии DirectX. Сейчас пишу прототип на Direct3D. Или я неправ? Просто Direct3D для решения 2D-задачи... Просто непривычно.
NB>DirectX любой версии тащит за собой все предыдущие, для совместимости
Думаете, стОит использовать именно DirectDraw? Понимаю, что логичней, но... Не могу сформулировать в вопрос чувства. Как-никак 7-ая версия...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: [GDI] Узкое место - StretchBlt. Возможна ли альтернат
Здравствуйте, Andrew S, Вы писали:
A>>Думаете, стОит использовать именно DirectDraw? Понимаю, что логичней, но... Не могу сформулировать в вопрос чувства. Как-никак 7-ая версия...
AS>Нет, не стОит. Там практически не поддерживается аппаратное ускорение, даже для блиттера (по-крайней мере, я для себя в свое время такие выводы сделал, потестировав производительность блиттинга директдрава и gdi). Почти все современные 2d игрушки используют direct3d.
Благодарю. Выполненные тесты и мнение опытного разработчика — то что было надо. Буду копать в сторону Direct3D
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: [GDI] Узкое место - StretchBlt. Возможна ли альтерна
A>>>>Думаете, стОит использовать именно DirectDraw? AS>>>Нет, не стОит. Там практически не поддерживается аппаратное ускорение, даже для блиттера (по-крайней мере, я для себя в свое время такие выводы сделал, потестировав производительность блиттинга директдрава и gdi). Почти все современные 2d игрушки используют direct3d.
S>Видимо во времена ваших тестов самыми распространёнными картами были S3 Trio
Видимо. Взгляните на интерфейсы DDI и DDDI — посмотрите, что мешает делать аппаратный стретч и в ddraw и в gdi одновременно? Поэтому, собственно, разницу между стретчем в ddraw и gdi найти будет трудно, если у разработчиков драйверов голова и руки были на месте.
А тестировалось это дело все на MX400. Я не претендую на полную объективность, отнюдь. Если у вас есть другие данные и они подтверждаются практикой — велкам, вам только спасибо скажут.
Здравствуйте, Sapersky, Вы писали:
S>Здравствуйте, spbAngel, Вы писали:
A>>Здравствуйте, Andrew S, Вы писали:
A>>>>Думаете, стОит использовать именно DirectDraw? AS>>>Нет, не стОит. Там практически не поддерживается аппаратное ускорение, даже для блиттера (по-крайней мере, я для себя в свое время такие выводы сделал, потестировав производительность блиттинга директдрава и gdi). Почти все современные 2d игрушки используют direct3d.
S>Видимо во времена ваших тестов самыми распространёнными картами были S3 Trio S>AFAIK, DirectDraw умеет делать stretch с фильтрацией на большинстве современных и не очень видеокарт (начиная где-то с TNT). S>Хотя у некоторых карт есть специфические особенности, например, у Radeon'ов (по крайней мере 9000'ой серии) размер поверхности, с которой можно делать stretch, ограничен максимальным размером текстуры (видимо, ATI'шники реализовали stretch через наложение текстуры; у NVidia всё "по-честному", размер поверхности ограничен только объёмом видеопамяти). Похожие проблемы у интегрированного видео на i915 — там при превышении макс. размера текстуры всё начинает сильно тормозить. На старом интегрированном видео (i810, i815 и вроде i845) аппаратный stretch через DirectDraw не работает, хотя текстуры накладывать они могут.
S>В D3D ограничение на размер текстуры официальное, т.е. больше — однозначно нельзя. Обычный макс. размер для карты "средней устарелости" (ранние GeForce, Radeon) — 2048 * 2048.
Respect. Когда-нибудь, и я буду такими данными делиться. А пока, вот сам узнаю. Глубоко копаешь.
S>А игрушки используют D3D главным образом для спецэффектов вроде полупрозрачности, поворота картинки и т.п. Этого в DirectDraw действительно нет.
Спасибо за инфу. Думается, что это может пригодится в будущем. Посему, всё таки остановим выбор на D3D.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: [GDI] Узкое место - StretchBlt. Возможна ли альтерна
От:
Аноним
Дата:
10.11.06 17:44
Оценка:
Здравствуйте, Andrew S, Вы писали:
A>>>>>Думаете, стОит использовать именно DirectDraw? AS>>>>Нет, не стОит. Там практически не поддерживается аппаратное ускорение, даже для блиттера (по-крайней мере, я для себя в свое время такие выводы сделал, потестировав производительность блиттинга директдрава и gdi). Почти все современные 2d игрушки используют direct3d.
S>>Видимо во времена ваших тестов самыми распространёнными картами были S3 Trio
AS>Видимо. Взгляните на интерфейсы DDI и DDDI — посмотрите, что мешает делать аппаратный стретч и в ddraw и в gdi одновременно? Поэтому, собственно, разницу между стретчем в ddraw и gdi найти будет трудно, если у разработчиков драйверов голова и руки были на месте.
Уточню: под аппаратным stretch я подразумеваю полностью аппаратный, с перемещением видеопамять->видеопамять. В случае системная->видео скорость, действительно, мало отличается от GDI. Похоже что DirectDraw в этом случае переключается на обычный StretchBlt.
В варианте видео->видео DirectDraw, по моим тестам, быстрее GDI в десятки-сотни раз. Stretch на весь экран занимает, как правило, меньше миллисекунды даже на старых картах. К тому же он делается с фильтрацией независимо от версии Windows (StretchBlt может фильтровать только в NT).
Фактически скорость получается примерно такая же, как и в D3D, да и по некоторым косвенным признакам (см. в предыдущем сообщении про Radeon) можно судить, что аппаратный stretch DirectDraw ближе к D3D, чем к GDI.
Re[12]: [GDI] Узкое место - StretchBlt. Возможна ли альтерна
A>>>>>>Думаете, стОит использовать именно DirectDraw? AS>>>>>Нет, не стОит. Там практически не поддерживается аппаратное ускорение, даже для блиттера (по-крайней мере, я для себя в свое время такие выводы сделал, потестировав производительность блиттинга директдрава и gdi). Почти все современные 2d игрушки используют direct3d.
S>>>Видимо во времена ваших тестов самыми распространёнными картами были S3 Trio
AS>>Видимо. Взгляните на интерфейсы DDI и DDDI — посмотрите, что мешает делать аппаратный стретч и в ddraw и в gdi одновременно? Поэтому, собственно, разницу между стретчем в ddraw и gdi найти будет трудно, если у разработчиков драйверов голова и руки были на месте.
А>Уточню: под аппаратным stretch я подразумеваю полностью аппаратный, с перемещением видеопамять->видеопамять. В случае системная->видео скорость, действительно, мало отличается от GDI. Похоже что DirectDraw в этом случае переключается на обычный StretchBlt.
О как. А про то, что DDB вполне себе могут жить в видеопамяти, вы подумали? Интерфейс DDI\gdi вполне позволяет такие вещи, более того, он на них и ориентирован. Например, на моей машине блиттинг ddb-ddb (или ddb-ScreenDC) занимает в разы меньше времени, чем оный же для ddb-dib. При этом вызовы gdi вполне себе буферизируются, поэтому суммарная производительность вполне и вполне, опять же, при учете нормальных драйверов.
Думаю, вполне очевидно, что DDB в данном случае расположен в видеопамяти — указанную пропускную способность (почти 7.5 гб\с) системная память на моей машине не обеспечивает.
А>В варианте видео->видео DirectDraw, по моим тестам, быстрее GDI в десятки-сотни раз. Stretch на весь экран занимает, как правило, меньше миллисекунды даже на старых картах. К тому же он делается с фильтрацией независимо от версии Windows (StretchBlt может фильтровать только в NT).
Ок, возможно. По крайней мере, результаты для bitblt и stretchblt у меня для gdi отличались в разы. Приведете тесты?
А>Фактически скорость получается примерно такая же, как и в D3D, да и по некоторым косвенным признакам (см. в предыдущем сообщении про Radeon) можно судить, что аппаратный stretch DirectDraw ближе к D3D, чем к GDI.
Все зависит от реализации. DDI предоставляет разработчикам полные возможности по аппаратному ускорению стретча в gdi. Я встречал реализации, где блиттинг в ddraw вообще не ускорялся, судя по ощущениям. (i740, такой обрезок, если помните)
Здравствуйте, Andrew S, Вы писали:
AS>О как. А про то, что DDB вполне себе могут жить в видеопамяти, вы подумали? Интерфейс DDI\gdi вполне позволяет такие вещи, более того, он на них и ориентирован. Например, на моей машине блиттинг ddb-ddb (или ddb-ScreenDC) занимает в разы меньше времени, чем оный же для ddb-dib. При этом вызовы gdi вполне себе буферизируются, поэтому суммарная производительность вполне и вполне, опять же, при учете нормальных драйверов.
Про DDB знаю. Но от применения отпугивало вот это самое "могут жить" (в DirectDraw, если указал в видео — 99% будет в видео); отсуствие каких-либо эффектов, даже примитивного цветового ключа; и ещё некоторые странные побочные эффекты вроде "остановки времени", т.е. замеряемое QueryPerformanceCounter время блиттинга стремится к 0, хотя при большом количестве циклов невооружённым глазом видно, что оно явно не нулевое. Причём не только я с этим сталкивался. Не знаете, как это можно объяснить (не принципом же относительности Эйнштейна ?
А>>В варианте видео->видео DirectDraw, по моим тестам, быстрее GDI в десятки-сотни раз. Stretch на весь экран занимает, как правило, меньше миллисекунды даже на старых картах. К тому же он делается с фильтрацией независимо от версии Windows (StretchBlt может фильтровать только в NT). AS>Ок, возможно. По крайней мере, результаты для bitblt и stretchblt у меня для gdi отличались в разы. Приведете тесты?
Тест (exe): http://slil.ru/23397272
Могу и исходники выложить (Delphi), но ничего сложного там нет — создаётся первичная поверхность, клиппер, поверхность с картинкой (в качестве картинки — снимок рабочего стола). Картинке делается Blt на экран безо всяких задних буферов.
AS> Все зависит от реализации. DDI предоставляет разработчикам полные возможности по аппаратному ускорению стретча в gdi. Я встречал реализации, где блиттинг в ddraw вообще не ускорялся, судя по ощущениям. (i740, такой обрезок, если помните)
i740 — это скорее "первый блин комом" Так что кривость драйверов неудивительна.
И даже если DirectDraw не ускоряется — то во всяком случае он не медленнее GDI/DDB, так? A вот наоборот — легко, например, DDB на Radeon 9000 + Win98 тормозит сильнее DIB.
Впрочем, здесь я сам начинаю увлекаться седой стариной. Лучше было бы подумать о Висте, применительно к которой это обсуждение вообще будет бессмысленным, по причине реализации GDI через D3D.
Re: [GDI] Узкое место - StretchBlt. Возможна ли альтернатива
Советую перейти на ренедринг OpenGL.
У меня есть опыт рендеринта с масштабированием огромных рисунков через DirectX, OpenGL, GDI и GDI+.
GDI+ тормозит всегда, даже на простейших операциях. То есть вообще всегда. Любая серьёзная графика на GDI+ это слайд-шоу. GDI тормозит иногда, но в целом масштабирование почти всегда грузит процессор на 100%. В отличие от предыдущих вариантов, DirectX это хорошо в плане скорости, даже очень хорошо. Первая же моя программа с прокруткой и масштабированием так и не смогла загрузить процессор больше чем на 5%, и то небось оконными сообщениями. OpenGL порой несколько медленее, но у OpenGL есть ряд серьёзных преимуществ для "не игр". Во-первых, OpenGL не надо распространять, она всегда есть. У меня программа на DirectX9 отказывалась запускатся на голой Windows 2000 SP4 (что вобщем-то нормально). Для тестирования на "плохих" видеокартах я запускал программу внутри VMWare — практически дохлый номер запустить там DirectX. С OpenGL ситуация прямо противоположная — программа запустилась на Windows 2000 SP4 внутри VMWare без проблем. Наблюдались только небольшие артефакты текстурирования, а в целом всё вполне прилично, включая (тут я был в шоке) производительность. Во-вторых, OpenGL не навязывает способ хранения данных, не принуждая к созданию разного рода буферов вершин. В-третьих, OpenGL поддерживает отрисовку квадратов (glBegin(GL_QUADS)). Вобщем советую.
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, spbAngel, Вы писали:
A>Советую перейти на ренедринг OpenGL. A>OpenGL порой несколько медленее, но у OpenGL есть ряд серьёзных преимуществ для "не игр". Во-первых, OpenGL не надо распространять, она всегда есть. У меня программа на DirectX9 отказывалась запускатся на голой Windows 2000 SP4 (что вобщем-то нормально).
Если нужна только "прокрутка и масштабирование", то можно использовать DDraw, причём хоть 1-ю версию, которая есть в составе любой Windows (последняя, 7-я, от неё отличается не сильно).
Если нужны спецэффекты и соотвественно D3D/OGL — тогда да, согласен, OpenGL в плане распространения удобнее. Рекомендовать использовать старые версии D3D я буду разве что человеку, имеющему соотвествующий опыт/наработки, или же врагу, чтоб помучился
A>OpenGL не навязывает способ хранения данных, не принуждая к созданию разного рода буферов вершин.
D3D не принуждает создавать буферы — см. DrawPrimitiveUP.
Буферы нужны при наличии большого кол-ва полигонов (>1000) и видеокарты с HWTnL, чтобы эта видеокарта смогла перемолоть их с максимальной эффективностью (буферы могут храниться в видеопамяти -> не надо на каждом кадре гонять геометрию через AGP). В OpenGL есть аналог в виде расширения (VBO).
Re[3]: [GDI] Узкое место - StretchBlt. Возможна ли альтернат
AS>>О как. А про то, что DDB вполне себе могут жить в видеопамяти, вы подумали? Интерфейс DDI\gdi вполне позволяет такие вещи, более того, он на них и ориентирован. Например, на моей машине блиттинг ddb-ddb (или ddb-ScreenDC) занимает в разы меньше времени, чем оный же для ddb-dib. При этом вызовы gdi вполне себе буферизируются, поэтому суммарная производительность вполне и вполне, опять же, при учете нормальных драйверов.
S>Про DDB знаю. Но от применения отпугивало вот это самое "могут жить" (в DirectDraw, если указал в видео — 99% будет в видео); отсуствие каких-либо эффектов, даже примитивного цветового ключа; и ещё некоторые странные побочные эффекты вроде "остановки времени", т.е. замеряемое QueryPerformanceCounter время блиттинга стремится к 0, хотя при большом количестве циклов невооружённым глазом видно, что оно явно не нулевое. Причём не только я с этим сталкивался. Не знаете, как это можно объяснить (не принципом же относительности Эйнштейна ?
Знаю. Это можно объяснить конвейером операций gdi. см. GdiFlash — batch mode.
Более того, это видет к другим интересным эффектам — асинхронности выполнения операций, например, вы можете делать blt DDB и DIB параллельно, что снижается затраты на блиттинг DDB до 0. Протестировать это можно, делая bitblt с диб секции на экран и делая сначала biblt с dib секции в ddb, а затем уже на экран. Получается, что блиттинг из DDB на экран — бесплатен в плане общей производительности.
А>>>В варианте видео->видео DirectDraw, по моим тестам, быстрее GDI в десятки-сотни раз. Stretch на весь экран занимает, как правило, меньше миллисекунды даже на старых картах. К тому же он делается с фильтрацией независимо от версии Windows (StretchBlt может фильтровать только в NT). AS>>Ок, возможно. По крайней мере, результаты для bitblt и stretchblt у меня для gdi отличались в разы. Приведете тесты?
S>Тест (exe): http://slil.ru/23397272
1. То, что GDI в масштабировании провалилась — ну, в общем, согласен. Но это однозначно проблемы драйверов, повторюсь, все интерфейсы для аппаратной реализации масштабирования в DDI есть.
2. Результаты DD blt и stretch — нереальны. У меня 6600 GT c видео на 1200 (GDDR3). Итого при 128 битном доступе это дает максимум 20 мб\с. При честном переносе из одной области памяти в другую получаем примерно 8-10 мб\с, что соответствует полученным мной для gdi результатам DDB. Каким образом у вас получается 600 гб\с? Причем как в блиттинге, так и в стретче?
S>Могу и исходники выложить (Delphi), но ничего сложного там нет — создаётся первичная поверхность, клиппер, поверхность с картинкой (в качестве картинки — снимок рабочего стола). Картинке делается Blt на экран безо всяких задних буферов.
Но резульаты для DDraw нереальны.
AS>> Все зависит от реализации. DDI предоставляет разработчикам полные возможности по аппаратному ускорению стретча в gdi. Я встречал реализации, где блиттинг в ddraw вообще не ускорялся, судя по ощущениям. (i740, такой обрезок, если помните)
S>i740 — это скорее "первый блин комом" Так что кривость драйверов неудивительна. S>И даже если DirectDraw не ускоряется — то во всяком случае он не медленнее GDI/DDB, так?
Не так. Может быть по-всякому — зависит от фантазии разработчика.
A вот наоборот — легко, например, DDB на Radeon 9000 + Win98 тормозит сильнее DIB.
А вот это уже пример лени разработчиков драйвера.
S>Впрочем, здесь я сам начинаю увлекаться седой стариной. Лучше было бы подумать о Висте, применительно к которой это обсуждение вообще будет бессмысленным, по причине реализации GDI через D3D.
??? Насколько я помню, они там переработали модель DDI, и вместо DirectХ теперь WGF, а директх9 и ниже (а также модель драверов DDI) эмулируется.
Здравствуйте, Andrew S, Вы писали:
S>>Про DDB знаю. Но от применения отпугивало вот это самое "могут жить" (в DirectDraw, если указал в видео — 99% будет в видео); и ещё некоторые странные побочные эффекты вроде "остановки времени", т.е. замеряемое QueryPerformanceCounter время блиттинга стремится к 0, хотя при большом количестве циклов невооружённым глазом видно, что оно явно не нулевое. Причём не только я с этим сталкивался. Не знаете, как это можно объяснить (не принципом же относительности Эйнштейна ?
AS>Знаю. Это можно объяснить конвейером операций gdi. см. GdiFlash — batch mode.
Теоретически — да, похоже на правду, многочисленные вызовы BitBlt откладываются в буфер, но не выполняются, замеряемое время очень мало. Потом Windows решает наконец их выполнить, получаем заметные визуально, но необнаруживаемые бенчмарком тормоза.
Практически — GdiGetBatchLimit у меня возвращает 20, т.е. 1000 вызовов BitBlt закэшироваться никак не могут. К тому же GdiSetBatchLimit(1) и GdiFlush после каждого BitBlt на ситуацию никак не влияют.
Хотя может быть, у драйвера своя очередь команд, независимая от GDI'шной.
AS>2. Результаты DD blt и stretch — нереальны. У меня 6600 GT c видео на 1200 (GDDR3). Итого при 128 битном доступе это дает максимум 20 мб\с. При честном переносе из одной области памяти в другую получаем примерно 8-10 мб\с, что соответствует полученным мной для gdi результатам DDB. Каким образом у вас получается 600 гб\с? Причем как в блиттинге, так и в стретче?
В точности те же симптомы, что и у меня с GDI/DDB.
Впрочем, здесь дело может быть не (или не только) в буферизации. При вызове Surface.Blt я не указал DDBLT_WAIT, хотя, наверное, надо было — возможно, без этого флага на большую часть вызовов драйвер возвращает DDERR_WASSTILLDRAWING и ничего не делает.
C Radeon 9000 и интегрированной i915 такого эффекта нет, то ли они асинхронность не поддерживают, то ли у драйвера DDBLT_WAIT зашито по умолчанию. Пробовал задать принудительно DDBLT_DONOTWAIT и DDBLT_ASYNC — всё равно меряется правильно.
Новая версия с DDBLT_WAIT и возможностью тестировать режимы по отдельности, чтобы удобнее было засекать время по часам (мне с GDI/DDB так и пришлось делать — получилась примерно та же скорость, что и DDraw без stretch): http://slil.ru/23409314
S>>Лучше было бы подумать о Висте, применительно к которой это обсуждение вообще будет бессмысленным, по причине реализации GDI через D3D. AS>??? Насколько я помню, они там переработали модель DDI, и вместо DirectХ теперь WGF, а директх9 и ниже (а также модель драверов DDI) эмулируется.
Насчёт внутренних деталей я не в курсе, смысл в том, что StretchBlt должны наконец ускорить до подобающего уровня.
Re[16]: [GDI] Узкое место - StretchBlt. Возможна ли альтерна
AS>>Знаю. Это можно объяснить конвейером операций gdi. см. GdiFlash — batch mode.
S>Теоретически — да, похоже на правду, многочисленные вызовы BitBlt откладываются в буфер, но не выполняются, замеряемое время очень мало. Потом Windows решает наконец их выполнить, получаем заметные визуально, но необнаруживаемые бенчмарком тормоза.
Никаких визуально заметных тормозов. Как только достигается батч лимит, все работает линейно (с условием, конечно, что аппаратно ускоряемые операции не перемежаются с обычными). В моих тестах это вполне видно. Просто надо _правильно_ тестировать — не по _количеству_ выполнений, а выделять промежуток времени, считать количество вызовов и потраченное на них время. И не смешивать различные операции во время тестирования.
S>Практически — GdiGetBatchLimit у меня возвращает 20, т.е. 1000 вызовов BitBlt закэшироваться никак не могут. К тому же GdiSetBatchLimit(1) и GdiFlush после каждого BitBlt на ситуацию никак не влияют. S>Хотя может быть, у драйвера своя очередь команд, независимая от GDI'шной.
Вообще, это довольно непросто в текущем варианте DDI. Да, там есть возможность "отложить" обработку поверхности — но как и делает ли это хоть кто-нибудь — не знаю.
AS>>2. Результаты DD blt и stretch — нереальны. У меня 6600 GT c видео на 1200 (GDDR3). Итого при 128 битном доступе это дает максимум 20 мб\с. При честном переносе из одной области памяти в другую получаем примерно 8-10 мб\с, что соответствует полученным мной для gdi результатам DDB. Каким образом у вас получается 600 гб\с? Причем как в блиттинге, так и в стретче?
S>В точности те же симптомы, что и у меня с GDI/DDB.
Нет, мне думается, что не те же.
S>Впрочем, здесь дело может быть не (или не только) в буферизации. При вызове Surface.Blt я не указал DDBLT_WAIT, хотя, наверное, надо было — возможно, без этого флага на большую часть вызовов драйвер возвращает DDERR_WASSTILLDRAWING и ничего не делает.
Похоже на то.
S>C Radeon 9000 и интегрированной i915 такого эффекта нет, то ли они асинхронность не поддерживают, то ли у драйвера DDBLT_WAIT зашито по умолчанию. Пробовал задать принудительно DDBLT_DONOTWAIT и DDBLT_ASYNC — всё равно меряется правильно.
Может. Завтра посмотрю новый вариант на 6600 GT.
S>C Radeon 9000 и интегрированной i915 такого эффекта нет, то ли они асинхронность не поддерживают, то ли у драйвера DDBLT_WAIT зашито по умолчанию. Пробовал задать принудительно DDBLT_DONOTWAIT и DDBLT_ASYNC — всё равно меряется правильно. S>Новая версия с DDBLT_WAIT и возможностью тестировать режимы по отдельности, чтобы удобнее было засекать время по часам (мне с GDI/DDB так и пришлось делать — получилась примерно та же скорость, что и DDraw без stretch): S>http://slil.ru/23409314
Потестировал. Результаты примерно те же. В общем, что то не так вы делаете, явно. Получаемые для DD результаты анреал, как вы понимаете.
К тому же получаемые у вас результаты для DDB ниже, чем у меня. И меняеются довольно странно между запусками — от 3 до 6 гб\с, даже при большом числе итераций. У меня результаты стабильны, с точностью до кб\с.
Здравствуйте, Andrew S, Вы писали:
AS>Потестировал. Результаты примерно те же. В общем, что то не так вы делаете, явно. Получаемые для DD результаты анреал, как вы понимаете.
Cделал по принципу "крутимся в цикле до тех пор, пока общее время не превысит определённой константы".
На GDI/DDB теперь выдаёт похожие на правду результаты (практически равные DDraw), но вместо положенных 2 секунд крутится в цикле 15 (точнее, вместо любого интервала от 0.2 до 2 секунд получается 15).
Лог временных интервалов при этом имеет вид (в микросекундах):
Очень похоже на буферизацию. Сначала идёт добавление в буфер (очень быстро, 5-6 мкс; параллельно, возможно, выполнение), потом, когда место в буфере заканчивается, драйвер вынужден 15 секунд выполнять всё что туда набилось. Всего итераций получается 16386; размер буфера, видимо, 16384. Или больше, если оно параллельно выполняется.
Если предположить, что у вас на GeForce/DDraw то же самое (у вас есть другие идеи?), то единственный способ получить правильные результаты — забить буфер полностью, чтобы драйвер перешёл на синхронное исполнение команд. Но какой у GeForce размер буфера — неизвестно; может быть, он умеет параллельно выполнять команды с достаточной скоростью и его нужно забивать очень долго. Может быть, проявятся ещё какие-то эффекты, о которых я не имею представления.
В общем, новую версию я могу выложить, но гарантировать правильное измерение...
AS>К тому же получаемые у вас результаты для DDB ниже, чем у меня. И меняеются довольно странно между запусками — от 3 до 6 гб\с, даже при большом числе итераций. У меня результаты стабильны, с точностью до кб\с.
Такие колебания могут быть из-за использования QueryPerformanceCounter, если у вас соответствующий CPU:
AS>>Потестировал. Результаты примерно те же. В общем, что то не так вы делаете, явно. Получаемые для DD результаты анреал, как вы понимаете.
S>Cделал по принципу "крутимся в цикле до тех пор, пока общее время не превысит определённой константы". S>На GDI/DDB теперь выдаёт похожие на правду результаты (практически равные DDraw), но вместо положенных 2 секунд крутится в цикле 15 (точнее, вместо любого интервала от 0.2 до 2 секунд получается 15).
На мой взгляд, что-то вы не так считаете. В моем сампле все точно, работает ровно столько, сколько заказывали. Как будет время, надеюсь, до выходных — выкушу нужные части и выложу. Просто уже самому интересно
Выложил тест на фтп. Сравнивает производительность блиттера для DIB секции и DDB. На каждый тест — по секунду, и цикл наново. Итого — результаты раз в 2 секунды, клавиатуру опрашивается аналогично — раз в 2 секунды. Никаких задержек не наблюдается.
Доступные параметры: -w:width -h:height. Например, -w:64 -h:64.
Без параметров гадит непосредственно на весь экран, так что удобнее перенаправлять вывод в файл (тест консольный).
AS>>>Потестировал. Результаты примерно те же. В общем, что то не так вы делаете, явно. Получаемые для DD результаты анреал, как вы понимаете.
S>>Cделал по принципу "крутимся в цикле до тех пор, пока общее время не превысит определённой константы". S>>На GDI/DDB теперь выдаёт похожие на правду результаты (практически равные DDraw), но вместо положенных 2 секунд крутится в цикле 15 (точнее, вместо любого интервала от 0.2 до 2 секунд получается 15).
AS>На мой взгляд, что-то вы не так считаете. В моем сампле все точно, работает ровно столько, сколько заказывали. Как будет время, надеюсь, до выходных — выкушу нужные части и выложу. Просто уже самому интересно
Здравствуйте, Andrew S, Вы писали:
AS>Выложил тест на фтп. Сравнивает производительность блиттера для DIB секции и DDB. На каждый тест — по секунду, и цикл наново. Итого — результаты раз в 2 секунды, клавиатуру опрашивается аналогично — раз в 2 секунды. Никаких задержек не наблюдается.
AS>http://gzip.rsdn.ru/File/8583/BltTest.zip
AS>Доступные параметры: -w:width -h:height. Например, -w:64 -h:64. AS>Без параметров гадит непосредственно на весь экран, так что удобнее перенаправлять вывод в файл (тест консольный).
Запускаю на Radeon'е, тут же жму Esc. Жду 15 секунд
С размером битмапа 64 * 64 задержки нет — просто потому, что блит такого битмапа делается 5-6 мкс, и карта успевает выполнять команды синхронно.
Собственно результаты:
Src dib: 1024 x 768 x 32
Dst dib: 1024 x 768 x 32
driver loaded
bitmap created: 6a050681
Ok0
768, 1024, 32, 3072Ok // кстати, почему сначала 768, потом 1024? ничего не путаете?
Ok1
Output (32->32): GDI\DIB — 71.93 FPS, 226274962.14 BPS
GDI\DDB — 1166.87 FPS, 3670651626.92 BPS
Похоже на правду, но скорость DDB в 1.3 раза больше чем в моём тесте. На i915 — аж в 2.2 раза.
То ли DDB у вас "более DD", то ли меряете очень хитро (сначала грешил на то, что битмап у меня при выводе обрезается, и, может, это как-то неэффективно делается, да и выводится в окно, а не на экран. Сделал чтобы не обрезался и на экран — всё то же самое).
Ещё тестировал GeForce2MX400. Похоже, там для DDraw есть аналогичный радеоновскому буфер, но работает он несколько более сложным образом:
DDB там не ускорялся, т.к. Win98. А в вашем тесте ещё и глючил, при запуске на полный экран — подвисание, если не на полный — выдаёт нечто совсем уж странное:
Src dib: 128 x 128 x 32
Dst dib: 128 x 128 x 32
driver loaded
bitmap created: f12 // странный handle, битмап не создался, что ли?
Ok0
128, 128, 32, 512Ok
Ok1
8 Гб/c на 150 Мгц SDR — это нечто Ладно, спишем на устаревшую и кривую ОС.
Кстати, по поводу гигабайтов в секунду. Мне кажется, результаты нужно умножать на 2, т.к. выполняется 2 операции, чтение и запись. Или видеокарты умеют их как-то распараллеливать?
Если умножать — тогда врёт и моя программа, намерившая 1.4 Гб/c при макс. теоретической 2.4 Гб/c.