_BC_ Протестить сейчас не могу - комп не тот, но как доберусь попробую. Извини за отсутствие - переезжал с одной квартиры на другую. Про твой подход к выводу на экран - работа проделана значительная, но к сожалению (вот сейчас ATI RAGE 128 expert - очень старая, но мой драйверок вывел картинку и на ней хм.. а твой конечно же ничего не выведет) Кстати 25 буду в Москве ...
последний кстати только для gf 8xxx. Пока судя по предварительным результатам, работает везде кроме 8xxx. Подожду как владельцы 8800GTS потестят последний аттач, пока же попробую добавить поддержку ATi.
_BC_ пока же попробую добавить поддержку ATi. Ну тогда покроешь 85% современных карт что есть хорошо. Подожду как владельцы 8800GTS потестят последний аттач После 28, раньше не доберусь.
похоже, что на gf8 драйвера вообще отрубают доступ к регистрам, с которыми работает VBE. Даже старые, совместимые с VGA, регистры CRT-контроллера содержат в себе фейк -- как будто бы выставлен классический режим 640x480x16. Найти бы кого-нть с GeForce 8400*, 8500*, 8600* для теста. Если на них то же самое, что и на 8800 -- то проще будет купить самую дешевую gf8-карту и поэкспериментировать с ней вживую. 8400GS стоит порядка 50$. Только надо убедиться, что она по нужным регистрам совместима с 8800, т.е. если на ней тест не сработает -- значит совместима. На ати нужны видеобиосы к новым картам, пока почти разобрался как работать с "первым поколением", вплоть до X700. С новыми гораздо легче т.к. на них теперь есть даташиты, правда довольно аскетичные, поэтому видеобиос всё же не помешает.
Мож прямой доступ к VRAM через DirectDraw, поможет чем нибудь. Код (Text): #include "ddraw.h" HWND ghWnd,mhWnd; short * scr; bool appAct = false; IDirectDraw * DirDraw; LPDIRECTDRAWSURFACE DSurface; DDSURFACEDESC DDSD; int _fastcall Random (int val) { static int RndSeed; __asm { Mov Eax, ecx IMUL EDX,RndSeed,0x8088405 INC EDX MOV RndSeed,EDX MUL EDX MOV EAX,EDX } } void OpenDD () { DirectDrawCreate (0, &DirDraw,0); DirDraw->SetCooperativeLevel (mhWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); DDSD.dwSize = sizeof(DDSD); DDSD.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; DDSD.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; DDSD.dwBackBufferCount = 1; DirDraw->CreateSurface(&DDSD, &DSurface, 0); DSurface->Lock (0, &DDSD, 0, 0); DSurface->Unlock(DDSD.lpSurface); scr = (short*)DDSD.lpSurface; appAct = true; } CloseDD () { appAct = false; Sleep (100); DSurface->Release(); DirDraw->Release(); } /* main window procedure */ long _stdcall MainWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_CREATE: mhWnd = hWnd; OpenDD (); break; case WM_CLOSE: close: DestroyWindow (hWnd); break; case WM_DESTROY: CloseDD (); PostQuitMessage (0); break; case WM_KEYDOWN: switch (wParam) { case VK_ESCAPE: goto close; } } return DefWindowProc (hWnd, uMsg, wParam, lParam); } int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { char szAppName[]="WIN32APP"; MSG msg; WNDCLASS wndclass; /* Register the frame class */ wndclass.style = 0; wndclass.lpfnWndProc = &MainWndProc;//(WNDPROC) wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = 0; wndclass.hCursor = LoadCursor (NULL,IDC_ARROW); wndclass.hbrBackground = 0; wndclass.lpszMenuName = szAppName; wndclass.lpszClassName = szAppName; if (!RegisterClass (&wndclass) ) return false; /* Create the frame */ ghWnd = CreateWindow (szAppName, szAppName,//"DDraw APP", WS_POPUP, 0,//CW_USEDEFAULT, 0,//CW_USEDEFAULT, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), 0,//NULL, 0,//NULL, 0,//hInstance, 0); ShowWindow (ghWnd, SW_SHOW); UpdateWindow (ghWnd); while (true) { if (PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE)) { if (GetMessage(&msg, 0, 0, 0) ) { TranslateMessage(&msg); DispatchMessage(&msg); } else return true; } if (appAct) scr[ Random (800*600)] = Random (65535); } return 0; }
Here it comes ATI! Поддержку сделал для всех карт (точнее, кроме начала 90-х гг.), но для новых опять-таки не отлаживал и не тестил, может сглюкнуть по моей вине. Под новыми в данном случае понимаются те, что старше X1300. ATI в отличие от нвидии на свои девайсы не выкладывает списки ID'шников, поэтому брал их с pciids, там довольно мутноватый формат имен и нет некоторых новых карт (еще не добавили походу). Впрочем, вывод имен карт -- фича чисто бонусная, имена карт изначально можно было и не выводить. С 8ххх скорее всего буду решать вопрос покупкой 8400GS, если она окажется совместимой с 8800 по юзаемым регистрам. [see newer version below]
8500 GT/8800 GTS 640M An error occured while drawing З.Ы. Разрешение экрана [from hardware] определяет неправильно? Мля.. это ж для ati
тему невнимательно читал. На данный момент поддержка для всех ати, которую почему-то никто не тестит (я тестил на X700 Pro и на IGP Radeon Xpress 200M) и всех нвидий кроме gf 8xxx, поддержка которых на очереди. На gf8 это больше, чем вопрос принципа -- на них не работают ring0-отладчики, странно, что это еще мало кто заметил.
раздобыл 8400GS и уже немного успел ее "пощупать за вымя". Изменения по сравнению с предыдущими картами -- весьма существенные. Большинство нововведений проистекает от драйверов, но есть и кое-что принципиально новое. Это новое было известно заранее, от разбора видеобиоса, поэтому на системе без установленных драйверов к 8400GS тест успешно заработал. Я чуть было не успел расстроиться, подумав, что выкинул на ветер 1400р. Но после установки прилагающихся драйверов всё встало на свои места. Итак, что мы имеем: - r0-отладчики действительно не работают, как и было обещано. Для этого не надо ничего особенного, типа висты, аеро, каких-либо специфичных настроек и тп -- ничего такого. Обыкновенная XP SP2, DirectX 9c, обыкновенные драйвера c диска, дефолтные настройки -- и понеслось, по кочкам. - фреймбуфер более не находится в видеопамяти. BAR в +14h в pci conf по-прежнему указывает на видеопамять, но для того, чтобы добраться до фреймбуфера, надо брать базу из +1Ch, которая указывает на некий диапазон размером 32Мб, в котором и находится фреймбуфер. Возможно, что он отображается на какую-то часть основного диапазона, не проверял. Но та же VBE c gf8xxx берет базу фреймбуфера исключительно из +1Ch. - фреймбуфер начинается не с начала этой базы -- та самая "вторая составляющая". Что VBE, что драйвера винды используют смещение +1000000h, т.е. +16Мб. Таким образом, адрес экранной поверхности теперь получается как сумма 3х слагаемых: вышеупомянутый BAR из pciconf[1Ch] + 1000000h + cмещение primary surface. - самое интересное теперь -- структура фреймбуфера. Нвидиавские драйвера включают весьма мутный режим, в котором фреймбуфер нелинеен. Теперь экран разбивается на квадратные tile'ы, внутри которых довольно замысловатое распределение пикселов. На эту тему наверное тисну небольшую статейку, с картинками и алгоритмом преобразования экранных координат в смещение во фреймбуфере. Алго пока довольно громоздкий, но можно сделать 100%-табличным. Сами тайлы идут во фреймбуфере линейно, как раньше пикселы, т.е. слева направо, сверху вниз, а вот внутри тайла уже начинается искривление пространства. Ни за что б не подумал, что после того, как ушли в забвение битовые плоскости, защелки, и прочая планарная хренатень, может понадобится столько возни, чтобы нарисовать банальную горизонтальную линию пикселов. - драйвера блокируют многие интересные регистры, среди которых и те, которые используются VBE-функциями. Это на данный момент самая главная проблема. С этих залоченных регистров как раз и получались адрес и характеристики primary surface для прямого рисования во фреймбуфере. Собственно рисовать в нем я уже научился, надо только узнать, как снимать эту залочку с регистров. Как отключать tile-режим уже тоже (скорее всего) известно, но чтобы это сделать, надо опять-таки добраться до регистров.
_BC_ На gf8 это больше, чем вопрос принципа -- на них не работают ring0-отладчики, странно, что это еще мало кто заметил. Заметили и не один раз - посмотри в форуме. Кстати я начал интерисоваться вопросом вывода на экран именно по этой причине. http://www.wasm.ru/forum/viewtopic.php?id=21398 и http://www.wasm.ru/forum/viewtopic.php?id=22678 Инет накрылся пишу строчки из И-клуба. GF 8800 - не работает похоже, что на gf8 драйвера вообще отрубают доступ к регистрам, с которыми работает VBE. С этим явлением встречался еще в VBIOS от старых карточек S3 64V+ Кстати SAVE_STATE и RESTORE_STATE в BIOS 8800 почему-то тоже не сохраняют текущий экран правильно - т.е. если насильно перейти в реальный режим, потом сохранить текущий видеорежим, включить текстовый, потом опять восстановить сохранение, то режим не восстанавливается. Лучше протестить на HD 2900 поскольку скорее всего такое поведение VGA CRT - есть подозрение на защиту контента от копирования. PS: похоже лучше соединить 2 технологии в одном драйвере для устойчивого вывода на экран, но твоя определенно может иметь приимущества (как и недостатки). Исходники драйвера не прилагаются ?
ну их поддержка ща вроде есть, только пока никто не нашелся, кто бы эту поддержку проверил, на HD2900. Насчет защиты от копирования -- там нет ничего такого. AFAIK их больше волновало как защитить передаваемый по кабелю до монитора/телека сигнал, а не как защитить FB от скриншотов и рисования. На данном этапе я могу рисовать и делать скриншоты с FB и в tile-режиме. Т.е. если как раньше, предварительно брать инфу об экране от ОС, а затем рисовать -- то больше ничего для счастья и не надо. Софтайс также можно пропатчить, чтобы он научился выводить на экран в тайлах. Судя по проявляющимся видеоглюкам, у него еще тоже проблемы с базой экрана в FB, т.к. на экран у него попадают явно не все пикселы. Там просто хитрая структура FB, которую надо либо учитывать, либо отключать на время вывода в FB, переводя в линейный режим. На это проще всего пропатчить софтайс -- чтобы он перед рисованием вырубал tile-mode и затем уже рисовал себя. Аналогично включать на выходе, после восстановления куска FB. Если это прокатит, то выглядеть будет довольно забавно -- нажимается ctrl+d. появляется айс, его окошко выглядит как обычно, а вот экран на фоне капитально запарафинился. Но при выходе из SI нормально восстанавливается в исходное состояние. А у тебя похоже были проблемы с получением адреса фреймбуфера, потому что несмотря на всю хитром#$%сть, flood fill всего экрана -- срабатывает. Я с этого и начал -- последовательное заполнение всего фреймбуфера, с небольшой задержкой, чтобы можно было наглядно видеть, каким образом пикселы попадают на экран. Исходники непременно будут, как только разберусь с заветной дверцей на gf8 и приведу их в божеский вид.
PROFi Кстати,возможно по этой причине иногда при частом переключении на 8800 бывает черный экран.Только перезагрузка спасает.
_BC_ как защитить передаваемый по кабелю до монитора/телека сигнал Не совсем так, имея доступ к регистрам карты можно читать ключ (тот который для шифрования посылается и монитором и видеокарточкой). Но вряд ли это поможет НО ВЕДЬ МОЖНО ПОДСУНУТЬ ВИРТУАЛЬНЫЙ МОНИТОР. на время вывода в FB, переводя в линейный режим. Абсолютно точно в GeForce 8800 перевод осущетвляется DirectDraw Surface Lock метод, т.е. если наклепать простенькое приложение пользовательского режима которое захватывает весь экран для прямого вывода и полсле Lock допустим завесить его back: jmp back то мой предыдущий отладчик исправно рисовал в FB и последний был линейным. Это кстати наиболее перспективный метод, поскольку полагаться на DrvCopyBits при работе с 3D графикой весьма проблематично FB не всегда вообще совпадает с тем что нашел (даже по смещению 1Сh) - это пройденный этап. Так что с исходниками. Кстати монитор новый купил 1600х1200 (LCD) а у тебя выдает прога вот что см аттач
_BC_ сделай в своей проге кнопку копирования инфы, чтобы данные ручками не перебивать итак, ATI Radeon Mobility X1400 "An error occured while drawing" Разрешение "from hardware" показывает неправильно: 2160x1250 вместо 1920x1200
PROFi поздравляю, повторю свой пост: На данный момент поддержка <...> и всех нвидий кроме gf 8xxx, поддержка которых на очереди. Jupiter ага, наконец-то новый ati. проще скриншот окошка проги сделать вообще-то. Ладно, добавлю copy to clipboard. а остальная инфа какая? В принципе, по разрешению уже догадываюсь, где надо фиксить.