RU/GTA:SA Resource Streaming: Difference between revisions

From Multi Theft Auto: Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(6 intermediate revisions by the same user not shown)
Line 69: Line 69:
[[File:Res_loader_sys.png|960px]]
[[File:Res_loader_sys.png|960px]]


===(Threaded) Resource Reading===
===(Поточность) Чтение Ресурсов===
There is an entirely separate system just for reading data chunks from disk, known as the '''streaming runtime'''. The game can create '''stream handles''' to files on disk. By calling the '''ReadStream''' function, an asynchronous request to read data from a stream handle is made. Reading activity is maintained in '''syncSemaphore''' structures that hold internal data about the reading process (like file handle or OVERLAPPED structure). Calling '''GetSyncSemaphoreStatus''' with the syncSemaphore index as argument will return the request status (i.e. reading has finished). '''CancelSyncSemaphore''' stops any asynchronous request.
Существует совершенно отдельная система просто для чтения порций данных с диска, известная как '''streaming runtime'''. Игра может создавать '''потоковые хэндлы''' для файлов на диске. При вызове функции '''ReadStream''', будет сделан запрос на чтение данных из потокового хендла. Процесс чтения обеспечивается структурами '''syncSemaphore''' которые удерживают внутренние данные о процессе чтения (такие как хэндл файла или структуры OVERLAPPED). Вызов '''GetSyncSemaphoreStatus''' c индексом syncSemaphore в качестве аргумента будет возвращать статус запроса (т.е. чтение завершено). '''CancelSyncSemaphore''' останавливает любые асинхронные запросы.


During start-up, the system checks the capabilities of the system. By default, '''threading is enabled'''. A read from GTA3.IMG is attempted using overlapped I/O to check for its support. The system will select the best compatible configuration. On modern machines, this means threading with overlapped I/O. In a worst case scenario, the game reads data synchronous on a single thread which halts game execution if data is read from slow storage media.
Во время старта, система проверяет возможности системы. По умолчанию, '''поточность включена'''. Для проверки поддержки этого, предпринимается попытка чтения из GTA3.IMG используя перекрытый ВВОД/ВЫВОД. Система выберет наилучшую совместимую конфигурацию. На современных машинах, это значит поточность с перекрытым ВВОДОМ/ВЫВОДОМ. В случае худшего сценария, игра читает данные синхронно в одиночном потоке с остановкой выполнения игры, если данные читаются из медленного медиа-хранилища.


===Conversion into Engine Objects===
===Преобразование в Объекты Движка===
The Streaming system natively maintains two reading slicers. A reading slicer checks which requested data is close in an .IMG container and reads multiple data in one go. Using modification of the logic the engine can support an arbitrary number of slicers, that all share chunks inside of a reading buffer. The more slicers, the smaller the reading buffer section for each. If data that is read does not fit into a single slicer, the Streaming system waits for all smaller requests to finish and then reads that big data on the first slicer using the whole reading buffer. The reading buffer size is determined by the biggest resource inside any registered .IMG container.
Система стриминга изначально обеспечивает два читающих слайсера. Читающий слайсер проверяет какие запрашиваемые данные ближе в .IMG контейнере и сразу читает несколько одномоментно. Модифицируя логику движка можно ввести поддержку произвольного числа слайсеров, которые все будут делиться порциями внутри буфера чтения. Чем больше слайсеров, тем меньше секция буфера чтения для каждого. Если прочитанные данные не входят в один слайсер, Система стриминга ждет завершения всех небольших запросов и тогда читает большие данные в первом слайсере используя весь буфер чтения. Размер буфера чтения определяется наибольщим ресурсом внтури всех зарегистрированных .IMG контейнеров.  


There are '''4 states''' that a '''slicer''' can be in: idle, buffering, loading and waiting. Idle slicers wait for requests that can occupy them. When slicers are buffering, they wait for their read requests to finish. Loading slicers wait until the game has loaded all game resources from them. Waiting is an exceptional status that is caused if a slicer is requested to push data for engine object conversion but the read requests have not finished yet.
Существует '''4 состояния''', которые могут иметь '''слайсеры''': простой, буферизация, загрузка и ожидание. Слайсеры с простоем ждут запроса, который может занять их. Когда слайсеры буферизируются, они ждут до конца свои запросы чтения. Слайсеры загрузки ждут пока игра загрузит все игровые ресурсы из них. Ожидание является исключительным статусом, который появляется если слайсер запрошен на передачу данных для преобразования объекта движка, но запрос чтения еще не завершен.


Loading is the most interesting status. The slicers push the raw data into loader routines along with their model IDs. Using the '''model ID''' the engine knows what that raw data is supposed to represent. For instance, model id 1361 is a model resource that is stored in a .DFF file. The loader routines usually load data in one go. If data is found too big, it can be '''loaded across multiple slicer pulses''' (the slicer resides in '''loading status'''). Then the data is processed in '''coroutine fashion'''. Natively, only '''texture dictionaries''' that exceed a certain block count use this feature. Also, the engine has been optimized to assume that all data is loaded in two slicer pulses (max.).
Загрузка самый интересный статус. Слайсер ложит необработанные данные в процедуру загрузчика вместе с их '''ID модели'''. Используя ID модели, движок знает как эти сырые данные должны быть представлены. Например, модель с id 1361 это ресурс модели, который хранится в .DFF файле. Процедуры загрузчика обычно загружают данные одномоментно. Если найденные данные слишком большие, они будут '''загружены несколькими толчками слайсера''' (слайсер находится в '''состоянии загрузка'''). Затем данные будут обработаны в '''сопрограмме'''. Изначально, только '''текстурные словари''' которые превышают определенное количество блоков используют эту возможность. Также, движок был оптимизирован считать что все данные загружаются в двух толчках слайсеров (максимально).  


Each slicer has its own '''syncSemaphore''' from the streaming runtime. The syncSemaphore index corresponds to the slicer index.
Каждый слайсер имеет свой '''syncSemaphore''' из streaming runtime. Индекс syncSemaphore соответствует индексу слайсера.


===COL/IPL Sector Loading===
===Загрузка Сектора COL/IPL===
The GTA:SA engine maps COLL and IPL sectors to world coordinate boundaries. When the streaming position (natively the player position) intersects with any sector, it will be requested to load. This activity is maintained in the '''Sectorizer''' template class. Every COLL and IPL sector is added into a quad tree to boost world area look-up. Sectors are allocated from a private data pool. Sectors have their own manager that specializes the Sectorizers activity (loading and unloading, pool index to model id conversion, sector marking logic).  
GTA:SA движок сопоставляет COLL и IPL секторы мировым координатам границ. Когда позиция стриминга (изначально позиция игрока) пересекается с любым сектором, он будет запрошен на загрузку. Эта работа обеспечивается в классе-шаблоне '''Sectorizer'''. Каждый COLL и IPL сектор добавляется в дерево квадрантов для ускорения обзора территории мира. Секторы выделяются из личного пула данных. Секторы имеют свой менеджер, которй специализируется на работе Sectorizer'ов (загрузка и выгрузка, преобразование индекса в id модели, логика маркировки сектора).


===Game Logic===
===Игровая Логика===
When the camera is close to the ground, the Streaming system pulses game activity management. Game activity is pre-loading of event models and streaming of event zones. These features have been disabled in MTA, but are interesting if SP support is considered.
Когда камера приближается к земле, Система стриминга обновляет толчком игровое окружение. Оно выполняет предзагрузку моделей событий и стриминг зон событий. Эти возможности были отключены в МТА, но являются интересными если рассматривается поддержка одиночной игры.


==Multiplayer Support==
==Поддержка Мультиплеера==
MTA:SA sets high demands for the GTA:SA engine. The streaming system was meant to be the central location to load resources from. Hence, natively, the system does not expect interaction of outside sources, such as the MTA runtime.
MTA:SA устанавливает высокие требования к движку GTA:SA. Система стриминга должна быть ключевым местом для загрузки ресурсов. Следовательно, изначально система не предполагает взаимодействия с внешними источниками, такими как MTA.  


To fix this problem, the entire system has to be understood and properly expanded. The '''RequestModel''' function and the '''FreeModel''' function are used to request resources for every game instance. By expanding the logic of these functions, MTA can offer custom resources to the game engine (i.e. models and collisions). Simple ASM hooks are insufficient, as the code requires heavy adjustments which need to be clear to every MTA developer. For instance, to prevent memory leaks and instability, the Streaming '''slicer''' activity and the loader queue have to be adjusted according to how MTA manipulates the resource status.
Для исправления этой проблемы, вся система должна быть разобрана и правильно расширена. Функции '''RequestModel''' и '''FreeModel''' используются для запроса ресурсов для каждого игрового экземпляра. Расширением этих функций, МТА может предложить пользовательские ресурсы игровому движку (т.е. модели и коллизии). Простого ASM хука недостаточно, потому что код требует тяжелой настройки которая должна быть понятна для каждого MTA разработчика. Например, для предотвращения утечек памяти и нестабильности, работа Поточного '''слайсера''' и очередь загрузчика должны быть настроены в соответствии с тем как MTA манипулярует статусами ресурса.


In MTA:Eir, the model support has been fixed by offering model resources on base model info request and preventing the deletion of custom collisions when COL sectors are being unloaded.
В MTA:Eir, поддержка моделей была исправления предложением ресурсов модели на базовой информации о ней и предотвращением удаления пользовательских коллизий когда COL секторы были выгружены.


==Ideas for Expansion==
==Идеи для Расширения==
Natively, the loader does not operate with perfect efficiency. As stated above, the system mimicks coroutine behavior. If very big .DFF models are loaded, the Streaming system can cause FPS drops. The way texture containers are loaded is imperfect, even if their loading is split into two pulses. The theory is that the conversion of every texture into a game instance is a complex task. Natively, streaming is not dependant on timing of the load process. If it were, then the system could yield when a TXD container takes too long to load.
Изначально, загрузчик не работает с достаточной эффективностью. Как сказано выше, система имитирует поведелние сопрограммы. Если очень большие .DFF модели были загружены, система стриминга будет вызывать падения FPS. Путь загрузки текстурных контейнеров не является совершенным, даже если их загрузка разделена на два толчка. В теории преобразование каждой текстуры в игровой экземпляр является сложной задачей. С самого начала, стриминг не зависит от времени процесс загрузки. Если бы это было, то система может отказывать когда TXD контейнер занимает слишком много времени для загрузки.


My proposal is that every slicer obtains a fiber in a MTA execution manager. Once per frame (and at all other plausible moments) all fibers will be pulsed, thus progressing resource loading. Since every fiber maintains its own runtime stack, complex code is avoided. When a certain quota of data is read from a RenderWare stream, the fiber's execution is yielded. Such a change in resource loading is going to smoothen the FPS of GTA:SA when traveling across the world.
Мое продложение заключается в том, чтобы какждый слайсер получил файбер в MTA менеджере. В каждом кадре (и во всех других вероятных мементах) все файберы были обновлены, таким образом обеспечивая загрузку ресурса. Так каждый файбер обеспечивает свой стек выполнения, что избегает сложного кода. Когда определенная часть данных прочитана из RenderWare потока, выполнение файбера обрывается. Такое изменение загрузки ресурсов сделает сглаженным FPS GTA:SA во время пересечения мира.


Problem with such a proposal is that the RenderWare streaming functions are hooked by the network module.
Проблемы с этим предложеним находится в том, что RenderWare функции стриминга присоединены к сетевому модулю.


===Fibered Loading===
===Fibered Загрузка===
This is a technique utilized in MTA:Eir to improve the performance of low-end computers. It generally smoothens the FPS count of the game by removing lag-spikes. In native GTA:SA, resources are mostly loaded in one go. Using [[MTA:Eir/functions/engineStreamingSetFiberedLoadingEnabled|fibered loading]] on the other hand, loading of resources depends on the time the Streaming system may take per frame. The time it may take is derived from the total execution time of last frame.
Эта техника используется в MTA:Eir для увеличения произвольности на слабых компьютерах. Как правило, он сглаживает количество FPS игры удалением острых лагов. В стандартной GTA:SA, ресурсы в основном загружаются одномоментно. С другой стороны, используя [[MTA:Eir/functions/engineStreamingSetFiberedLoadingEnabled|fibered loading]], загрузка ресурсов зависит от времени за которое Система стриминга может занимать в каждом кадре. Время которое может потребоваться, получается из общего времени выполнения последнего кадра.  


Imagine that a very big TXD container is stored inside of GTA3.IMG. Such resources take a relatively long time to be buffered into game memory and an initialization attempt during Streaming loading may cause a lagspike, since much data is processed at once. If fibered loading is enabled, a coroutine (a.k.a. fiber) is created for every resource loading ''slicer'' with its own execution stack. When the loader attempts to read resources from the buffer, the fiber executive manager checks whether the fiber has taken [[MTA:Eir/functions/engineStreamingSetFiberedPerfMultiplier|its time]] already. If so, it yields during the read process. Execution will continue next game frame.
Предполагается, что очень большие TXD контейнеры  хранятся в GTA3.IMG. Такие ресурсы забирают относительно много времени на буферизацию в игровую память и попытка инициализации пока стриминг загружается, может привести к лагам потому что все данные обрабатываются сразу. Если fibered загрузка включена, сопрограмма (т.н. fiber) создается для каждой ''слайсера'' загрузки ресурса с его исполнительным стеком. Когда загрузчик пытается прочесть ресурсы из буфера, исполнительный менеджер fiber'а проверяет был ли уже взят [[MTA:Eir/functions/engineStreamingSetFiberedPerfMultiplier|он в свое время]]. Если да, он останавливается во время процесса чтения. Выполнение будет продолжено в следующем игровом кадре.


[[en:GTA:SA_Resource_Streaming]]
[[en:GTA:SA_Resource_Streaming]]

Latest revision as of 15:58, 27 May 2014

Система GTA:SA Resource Streaming загружает данные из диска в игровую память. Она разделена на управление IMG контейнером, потоковым чтением ресурсов, преобразованием в игровые объекты, загрузка сектора COL/IPL и игровую логику. Она была создана для асинхронной загрузки ресурсов.

Известные типы ресурсов

Имя ID диапазон Описание
Модели (.DFF) 0-19999 Все игровые модели входят в эти ID. Внутренне этот диапазон дальше разделяется на подсекции объектов, автомобилей и педов.
Текстурные Словари (.TXD) 20000-24999 Содержит слоты текстурных словарей. Текстурные словари это контейнеры со всеми игровыми текстурами. Игра присваивает текстурные словари к моделям.
Секторы Столкновений (.COL) 25000-25255 Слоты хранят все загруженные секторы столкновений. Секторы столкновений это COLL контейнеры, которые могут ссылаться и простираться через внутриигровые границы (основано на зданиях, которые используют их).
IPL Секторы (.IPL) 25256-25510 Слоты содержат все загруженные IPL секторы. IPL секторы представлены бинарными .ipl файлами внутри .IMG контейнера. Игра загружает их внуть своих рамок только когда они будут необходимы.
Контейнеры Патчнодов (.DAT) 25511-25574 Патчноды выровнены на секторы 8*8 по 750*750 юнитам. Когда игра ссылаться на такой квадрат, она загружает связанные файлы патчнодов, которые нумерованы в соответствии с формулой (height * rowLen + rowIndex).
Блоки Анимаций (.IFP) 25575-25754 Блоки анимации содержат все последовательности анимаций. Модели могут ссылаться на анимационные блоки, поэтому они запрашивают их вместе.
Записи (.RRR) 25755-25819 Записи хранят предварительно записанные данные игровых движений. Эти игровые движения используются во время миссий когда вы гонитесь за кем-то или прицеливаетесь из окна пока друг ведет.

Описание

Управление IMG Контейнером

Во время инициализации движка, игра загружает файлы конфигурации, которые говорят ему какие .IMG контейнеры использовать. Когда Система стриминга инициализирована, она пытается загрузить зарегистрированные .IMG контейнеры. Каждый .IMG контейнер ссылается используя уникальный индекс внтури IMGFile массива. Игра держит открытыми хэндлы файлов .IMG контейнеров, так что она может всегда читать из них.

Когда .IMG контейнер будет загружен, каждый файл может представить новый ID ресурса внутри движка (структура CModelInfoSA). Модели получат ID путем сравнением их имен с .IDE записью. Если ничего не найдено, движок поддерживает небольшой кэш ресурса. Эти ресурсы еще могут быть загружены используя RequestSpecialModel. Текстурный Словарь получает новый ID. Имеется жесткий лимит в 5000 TXD. COLL и IPL секторы также получают новые ID основанные на порядке загрузки. Все остальные ресурсы поступают также, следую этим же принципам.

Внутренний CModelInfoSA массив представляет каждую запись ресурса в .IMG файлах. Движок поддерживает всего 26310 ресурсных ID.

Возможные состояния загрузки ресурса

Имя Описание
MODEL_UNAVAILABLE Ресурс не был загружен. Ни один из игровых ресурсов для этой записи не был загружен. Этот ресурс не используется ни одной из частей игрового движка.
MODEL_LOADED Этот ресурс был загружен Системой стриминга. Он готов быть использован игровым движком.
MODEL_LOADING Этот ресурс находится в очереди быть-загруженным. Он ожидает взятия Системой стриминга для чтения с диска.
MODEL_QUEUE Слайсер в настоящее время читает данные из диска для этого ресурса.
MODEL_RELOAD Этот ресурс в настоящее время загружается в сопрограмму. Данные которые с ним связаны слишком большие чтобы загрузить их сразу же.

Res loader sys.png

(Поточность) Чтение Ресурсов

Существует совершенно отдельная система просто для чтения порций данных с диска, известная как streaming runtime. Игра может создавать потоковые хэндлы для файлов на диске. При вызове функции ReadStream, будет сделан запрос на чтение данных из потокового хендла. Процесс чтения обеспечивается структурами syncSemaphore которые удерживают внутренние данные о процессе чтения (такие как хэндл файла или структуры OVERLAPPED). Вызов GetSyncSemaphoreStatus c индексом syncSemaphore в качестве аргумента будет возвращать статус запроса (т.е. чтение завершено). CancelSyncSemaphore останавливает любые асинхронные запросы.

Во время старта, система проверяет возможности системы. По умолчанию, поточность включена. Для проверки поддержки этого, предпринимается попытка чтения из GTA3.IMG используя перекрытый ВВОД/ВЫВОД. Система выберет наилучшую совместимую конфигурацию. На современных машинах, это значит поточность с перекрытым ВВОДОМ/ВЫВОДОМ. В случае худшего сценария, игра читает данные синхронно в одиночном потоке с остановкой выполнения игры, если данные читаются из медленного медиа-хранилища.

Преобразование в Объекты Движка

Система стриминга изначально обеспечивает два читающих слайсера. Читающий слайсер проверяет какие запрашиваемые данные ближе в .IMG контейнере и сразу читает несколько одномоментно. Модифицируя логику движка можно ввести поддержку произвольного числа слайсеров, которые все будут делиться порциями внутри буфера чтения. Чем больше слайсеров, тем меньше секция буфера чтения для каждого. Если прочитанные данные не входят в один слайсер, Система стриминга ждет завершения всех небольших запросов и тогда читает большие данные в первом слайсере используя весь буфер чтения. Размер буфера чтения определяется наибольщим ресурсом внтури всех зарегистрированных .IMG контейнеров.

Существует 4 состояния, которые могут иметь слайсеры: простой, буферизация, загрузка и ожидание. Слайсеры с простоем ждут запроса, который может занять их. Когда слайсеры буферизируются, они ждут до конца свои запросы чтения. Слайсеры загрузки ждут пока игра загрузит все игровые ресурсы из них. Ожидание является исключительным статусом, который появляется если слайсер запрошен на передачу данных для преобразования объекта движка, но запрос чтения еще не завершен.

Загрузка самый интересный статус. Слайсер ложит необработанные данные в процедуру загрузчика вместе с их ID модели. Используя ID модели, движок знает как эти сырые данные должны быть представлены. Например, модель с id 1361 это ресурс модели, который хранится в .DFF файле. Процедуры загрузчика обычно загружают данные одномоментно. Если найденные данные слишком большие, они будут загружены несколькими толчками слайсера (слайсер находится в состоянии загрузка). Затем данные будут обработаны в сопрограмме. Изначально, только текстурные словари которые превышают определенное количество блоков используют эту возможность. Также, движок был оптимизирован считать что все данные загружаются в двух толчках слайсеров (максимально).

Каждый слайсер имеет свой syncSemaphore из streaming runtime. Индекс syncSemaphore соответствует индексу слайсера.

Загрузка Сектора COL/IPL

GTA:SA движок сопоставляет COLL и IPL секторы мировым координатам границ. Когда позиция стриминга (изначально позиция игрока) пересекается с любым сектором, он будет запрошен на загрузку. Эта работа обеспечивается в классе-шаблоне Sectorizer. Каждый COLL и IPL сектор добавляется в дерево квадрантов для ускорения обзора территории мира. Секторы выделяются из личного пула данных. Секторы имеют свой менеджер, которй специализируется на работе Sectorizer'ов (загрузка и выгрузка, преобразование индекса в id модели, логика маркировки сектора).

Игровая Логика

Когда камера приближается к земле, Система стриминга обновляет толчком игровое окружение. Оно выполняет предзагрузку моделей событий и стриминг зон событий. Эти возможности были отключены в МТА, но являются интересными если рассматривается поддержка одиночной игры.

Поддержка Мультиплеера

MTA:SA устанавливает высокие требования к движку GTA:SA. Система стриминга должна быть ключевым местом для загрузки ресурсов. Следовательно, изначально система не предполагает взаимодействия с внешними источниками, такими как MTA.

Для исправления этой проблемы, вся система должна быть разобрана и правильно расширена. Функции RequestModel и FreeModel используются для запроса ресурсов для каждого игрового экземпляра. Расширением этих функций, МТА может предложить пользовательские ресурсы игровому движку (т.е. модели и коллизии). Простого ASM хука недостаточно, потому что код требует тяжелой настройки которая должна быть понятна для каждого MTA разработчика. Например, для предотвращения утечек памяти и нестабильности, работа Поточного слайсера и очередь загрузчика должны быть настроены в соответствии с тем как MTA манипулярует статусами ресурса.

В MTA:Eir, поддержка моделей была исправления предложением ресурсов модели на базовой информации о ней и предотвращением удаления пользовательских коллизий когда COL секторы были выгружены.

Идеи для Расширения

Изначально, загрузчик не работает с достаточной эффективностью. Как сказано выше, система имитирует поведелние сопрограммы. Если очень большие .DFF модели были загружены, система стриминга будет вызывать падения FPS. Путь загрузки текстурных контейнеров не является совершенным, даже если их загрузка разделена на два толчка. В теории преобразование каждой текстуры в игровой экземпляр является сложной задачей. С самого начала, стриминг не зависит от времени процесс загрузки. Если бы это было, то система может отказывать когда TXD контейнер занимает слишком много времени для загрузки.

Мое продложение заключается в том, чтобы какждый слайсер получил файбер в MTA менеджере. В каждом кадре (и во всех других вероятных мементах) все файберы были обновлены, таким образом обеспечивая загрузку ресурса. Так каждый файбер обеспечивает свой стек выполнения, что избегает сложного кода. Когда определенная часть данных прочитана из RenderWare потока, выполнение файбера обрывается. Такое изменение загрузки ресурсов сделает сглаженным FPS GTA:SA во время пересечения мира.

Проблемы с этим предложеним находится в том, что RenderWare функции стриминга присоединены к сетевому модулю.

Fibered Загрузка

Эта техника используется в MTA:Eir для увеличения произвольности на слабых компьютерах. Как правило, он сглаживает количество FPS игры удалением острых лагов. В стандартной GTA:SA, ресурсы в основном загружаются одномоментно. С другой стороны, используя fibered loading, загрузка ресурсов зависит от времени за которое Система стриминга может занимать в каждом кадре. Время которое может потребоваться, получается из общего времени выполнения последнего кадра.

Предполагается, что очень большие TXD контейнеры хранятся в GTA3.IMG. Такие ресурсы забирают относительно много времени на буферизацию в игровую память и попытка инициализации пока стриминг загружается, может привести к лагам потому что все данные обрабатываются сразу. Если fibered загрузка включена, сопрограмма (т.н. fiber) создается для каждой слайсера загрузки ресурса с его исполнительным стеком. Когда загрузчик пытается прочесть ресурсы из буфера, исполнительный менеджер fiber'а проверяет был ли уже взят он в свое время. Если да, он останавливается во время процесса чтения. Выполнение будет продолжено в следующем игровом кадре.