Флейм
GameDev.ru / Флейм / Форум / Блеск и нищета 32/64-битных консолей и ПК

Блеск и нищета 32/64-битных консолей и ПК

Поделиться
Страницы: 1 2 3 4 5 Следующая »
=A=L=X=Постоялецwww31 окт. 20174:39#0
P.S. Выделил эту и тему про 32-бита в сообщество: http://www.gamedev.ru/community/old_tricks/articles/

ОГЛАВЛЕНИЕ ПО СИСТЕМАМ

3DO Interactive Multiplayer
Playstation 1
Nintendo 64
Playstation 2

(помните, что иногда текст не влазит в один комментарий и растягивается на два и даже более)

8<-----------------------

Как и грозился в предыдущей теме про 8/16-битные системы переход к 32/64-битному железу потребует новой темы - и вот она здесь.
Напоминаю суть этой серии тем здесь, слегка перефразировав её из предыдущей:

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

32/64-битные консоли прежде всего интересны началом тотального перехода в 3D и их железо значительно обогатилось по сравнению видеочипами 2D-графики 8/16-битной эпохи.
Сперва я даже думал, что уже не смогу просто в режиме хобби/развлечения прочитать о столь сложной аппаратуре с точки зрения архитектуры для разработчика, однако, как оказалось, простые времена - простые решения.

Итак, первая консоль, которую я бы хотел разобрать по программно-аппаратным косточкам это конечно же незабвенная и легендарная...

Правка: 22 ноя. 2017 8:04

=A=L=X=Постоялецwww31 окт. 20175:38#1
Playstation 1 (она же - PSX)

Для начала вспомним историю. Появилась эта консоль в декабре 1994-го года. Другими словами всего через год после выхода псевдотрёхмерного Doom 1 и за полтора года до выхода Quake 1.
По данным с вики 3Dfx уже была основана как компания, но на рынок персоналок она войдёт позже - в 96-ом году. NVidia тоже уже была основана (в 93-ем), но первый видеоускоритель она выпустит только в 98-ом.
Таким образом PS1, обладавшая полноценным ускорителем трёхмерной полигональной графики фактически выступает в роли по меньшей мере одной из первых ласточек - возможно даже первой массовой машиной с аппаратным трёхмерным ускорением, хотя тут надо более аккуратно исследовать исторические реалии на предмет всяких 3DO и тому подобное.

Далее я очень кратко и сжато перескажу ключевые вещи из содержимого документа "Everything You Have Always Wanted to Know about the Playstation But Were Afraid to Ask" (http://hitmen.c02.at/files/docs/psx/psx.pdf), который подробно описывает архитектуру PS1 с точки зрения разработчика.

R3000A

В качестве ЦП в PS1 трудился MIPS R3000A - один из классических представителей RISC-архитектуры с частотой 33МГц. Регистровый банк - 32 целочисленных 32-битных регистра общего назначения повышенной ортогональности, плюс еще два 32-битных регистра в интегрированном модуле целочисленного деления/умножения. Ну и всякий прочий системный фарш. Единственное из любопытного что я могу вспомнить про архитектуру - это так называемый Delay Slot. Процессор появился еще без конвеера, но в качестве предтечи оного в нём всегда одна следующая инструкция извлекалась из памяти и дешифровалась в процессе выполнения текущей инструкции. Это правило было железобетонным и поэтому когда процессор встречал команду перехода (jump/branch), то сразу после перехода сперва выполнялась одна команда следующая за ним по старому адресу. Таким образом все команды переходов надо было "сдвинуть" на одну команду наверх, а если "сверху" команды не было - то добавить nop, чтобы всё вело себя без предсказуемо и без просадок. Это добавляло геморроя как в ассемблере, так и разработчикам компиляторов.

Под непосредственным управлением R3000A находилось 2Мб системной RAM и 2 сопроцессора.
Первый сопроцессор назывался Cop0 и по сути был менеджером виртуальной памяти и всяких утилитарных штук типа прерываний и реакций на ошибки.
Второй же сопроцессор назывался Cop2 и носил гордое название Graphics Transformation Engine (GTE).

GTE

Дело в том, что сопроцессора для вычислений с плавающей запятой в системе не было, но 3D-графика предполагала много всяких вычислений с вещественными числами. Поэтому вместо математического сопроцессора в R3000A впаяли сразу сопроцессор GTE - ровно то, что нужно было для 3D-графики - ни больше, ни меньше.
Это был классический сопроцессор - инструкции ему скармливал процессор, разбирая собственный поток инструкций и встречая специальный префикс. Выполняя свою инструкцию сопроцессор не мешал основному ЦП, то есть работал параллельно, но если основной ЦП пытался обратиться к нему в середине процесса - то он вынужден был остановится и подождать результат.
У GTE было 64 32-битных регистра - но все эти регистры были высокоспециализированными. Каждый из них хранил или возвращал вполне конкретные вещи для вполне конкретных вычислений нужных для графического пайплайна. Выражаясь современной терминологией GTE выполнял широкий набор довольно замысловатых инструкций выполняющих задачи T&L. Например у GTE была команда перемножающая точку на матрицу или команда обсчитывающая освещение точки от источника света. Параметры матрицы, к примеру, хранились в первых регистрах GTE - RxRy, выходные координаты точки сохранялись в регистрах MAC1/2/3, и так далее - регистров были десятки и все они были специфичны для тех или иных команд. Процессор мог загружать/сохранять данные в/из любого такого регистра, чем и обеспечивалось взаимодействие с системой.
Однако всё еще осложнялось (и ускорялось) тем, что все данные в GTE хранились с фиксированной точкой - причём в очень разных форматах. Например коэффициенты матриц хранились в формате 4:12 (знаковое 16-битное с двенадцатью битами после запятой), а вот коэффициенты трансляции в формате 20:12. Встречались еще форматы 16:16 и 28:4. В общем регистры GTE были воистину фаршем напополам с винегретом!

Поработав таким образом над исходными вершинами моделек, рассчитав им цвет и сконвертировав в целочисленные координаты screen-space-а процессор далее передавал данные в видеочип - в GPU.

Правка: 8 ноя. 2017 8:58

=A=L=X=Постоялецwww31 окт. 20177:21#2
GPU

Видеочип обладал собственной памятью VRAM в 1Мб в которую ЦП не имел доступа кроме как посредством плотного общения с GPU.

С GPU общение происходило через два 32-битных порта ввода-вывода отображенных в память ЦП.
Первый порт (Status/Control) при чтении возвращал самые основные статусные данные о состоянии видеочипа, например занят ли тот выполнением команды или свободен и ждёт новой. А при записи вменял одну из "глобальных команд" - например полный сброс видеочипа или установку видеорежима.
А вот второй порт (Data register) при записи помещал записываемое слово (в PS1 словом считается 32 бита) в FIFO-очередь команд. Видеочип ожидал от ЦП потока команд, которые по очереди выполнял. Команды были самые разные - от выставления параметров рендеринга (Render State) до отрисовки спрайта или треугольника. Все команды представляли из себя поток слов в заранее обозначенном формате - первое слово хранило идентификатор команды и самые важные параметры, далее следовали прочие данные, вплоть до огромных массивов при перекидывании битмапов. FIFO-очередь команд вмещала 16 слов (или 64 байта). Так как команды могли быть большими, то прежде чем записывать много данных туда надо было ждать опустошения очереди опрашивая регистр Status.
Чтобы процессору можно было не заниматься этой муторной работой один из семи DMA-каналов в системе был спроектирован специально для этого. В простом режиме он мог скормить в Data register большой банк данных, автоматически дожидаясь опустошения FIFO-очереди и подпитывая её по ходу дела. А вот в "сложном режиме" ему можно было скормить указатель на голову однонаправленного списка с данными в простом формате:
- Адрес следующего блока (FFFFFF для конца списка)
- Длина данных текущего блока в словах (может быть 0, тогда DMA-канал просто переходит к следующему блоку)
- Данные текущего блока (массив слов)
И таким образом "запитать" видеокарту на будущее большим и сложным набором команд к выполнению, который можно подготавливать долго и расчётливо.
В видеочипе не было Z-буфера и потому порядок отрисовки имел основополагающее значение - такое устройство очереди команд упрощало дело построения их в правильном порядке.

Вся VRAM в 1Мб с точки зрения GPU представлена как один большой битмап фреймбуфера 1024x512 16-битных пикселей. Забавно, что все данные поступающие для сохранения в VRAM никогда не указываются своими линейными адресами - всегда адресация идёт как бы к двум координатам (x,y) в этом фреймбуфере. Некоторое окно (границы которого программируются) в этом фреймбуфере отображается на дисплей (так что видеостраницы с vsync легко реализуются). Причём ему можно сменить битность с 16 бит на 24-битную (3 байта на пиксель). Но в этом режиме похоже не будет работать полупрозрачность и стенсиль (см. ниже), пояснений в документе нет.
Формат цветности - 1:5:5:5, где верхний бит трактуется по разному - смотря где он находится. Если это пиксель к записи во фреймбуфер, то это может быть бит полупрозрачности - тогда возможно на выбор 4 режима смешивания, со средним арифметическим в том числе. Если же это бит уже лежащий во фреймбуфере, то может быть включен режим Stencil check, запись пикселя будет отменяться, если бит зажжён. В режиме Stencil write любая запись пикселя во фреймуфер будет зажигать этот бит. В общем stencil как stencil.
В качестве текущей текстуры для текстурирования может быть выставлен блок из 256x256 пикселей (выбираемый с некоторой гранулярностью внутри фреймбуфера), причём внутри него с гранулярностью 8 пикселей могут быть выбраны "окна" для режимов с зацикливанием текстуры.
Сами текстуры могут быть в трёх цветовых форматах - 16, 8 и 4 бита на пиксель. Последние 2 требуют наличия Color Lookup Table (CLUT), т.к. байты хранят не сами цвета, а индексы в таблице из 16-битных цветов, причём таблицы эти так же представлены во фреймбуфере как бы просто полосками пикселей.

Перечислим вообще какие опции вообще возможны при рендеринге в качестве инструментов:
- полупрозрачность (однобитовая, по четырём возможным формулам, включая среднее арифметическое)
- текстурирование (правда совершенно без перспективной коррекции, что приводило к характерным искажениям)
- шейдинг для треугольников - как одноцветный так и по Гуро (вместе с текстурированием)
- автоматический дизеринг при рендере полигонов
- ограничение области рендера прямоугольным окном (хотя тут правильнее говорить о выборе произвольного прямоугольника во фреймбуфере как поверхности для рисования - то есть рендер в текстуру опять таки не вопрос и получается в этой системе с единым большим фреймбуфером автоматически)
- однобитный Stencil (в документации называется mask)

Итак, основная работа делалась с помощью списков команд.
Команд было много и разных - от отрисовки точек, спрайтов, полигонов (3 или 4 вершины), до закачки текстур или получения изображения в системную память обратно из видеокарты.
Например рассмотрим команду отрисовки монохромного треугольника, которая состоит из четырёх (32-битных) слов:
1) (байты) 0x20, B, G, R // 0x20 - код команды, BGR в 3-байтном формате
2) (полуслова) Y0, X0
3) (полуслова) Y1, X1
4) (полуслова) Y2, X2
Здесь видно, что координаты точек полигонов в видеочип передаются уже целочисленными в screen-space-е и по сути видеокарта занимается растеризацией без учета Z-координаты (и даже не имея Z-буфера).

Вот полный перечень команд с их кодами и кратким пояснением на английском:

Primitive drawing packets
 0x20     monochrome 3 point polygon
 0x24     textured 3 point polygon
 0x28     monochrome 4 point polygon
 0x2c     textured 4 point polygon
 0x30     gradated 3 point polygon
 0x34     gradated textured 3 point polygon
 0x38     gradated 4 point polygon
 0x3c     gradated textured 4 point polygon
 0x40     monochrome line
 0x48     monochrome polyline
 0x50     gradated line
 0x58     gradated line polyline
 0x60     rectangle
 0x64     sprite
 0x68     dot
 0x70     8*8 rectangle
 0x74     8*8 sprite
 0x78     16*16 rectangle
 0x7c     16*16 sprite
GPU command & Transfer packets
 0x01     clear cache
 0x02     frame buffer rectangle draw
 0x80     move image in frame buffer
 0xa0     send image to frame buffer
 0xc0     copy image from frame buffer
Draw mode/environment setting packets
 0xe1     draw mode setting
 0xe2     texture window setting
 0xe3     set drawing area top left
 0xe4     set drawing area bottom right
 0xe5     drawing offset
 0xe6     mask setting

Заключение

Таким образом видно, что архитектура PS1 уже по сути во многом предвосхищала будущее - задолго до эпохи аппаратного T&L в домашних видеокартах она делала это, правда средствами сопроцессора, плюс к тому концепция dedicated video memory с видеочипом как серверной сущностью, которой скармливается поток команд для параллельной работы с центральным процессором - всё это стояло сразу на шаг впереди glBegin/glEnd.

В общем впечатления остались довольно приятные - рассвет эпохи так сказать, первые ласточки, однако архитектура GPU в целом грамотная, хотя и предполагающая знание многих десятков и форматов и нюансов, но тем не менее это всё будет даже попроще пожалуй спецификации OpenGL 1.0. По крайней мере не сложнее. Биты все разложены логично и обоснованно.
Напомню еще, что первый релиз Direct3D случился двумя годами позже - в 96-ом. Хотя несомненно мысли вокруг аппаратных ускорений графики и API к ним бродили намного раньше - сама PS1 конечно появилась не на пустом месте.

Ну и нелишним будет продемонстрировать уровень графония тех лет и этого железа картинкой, лучше так сказать один раз увидеть:

Изображение

Правка: 8 ноя. 2017 8:57

monobogdanПостоялецwww31 окт. 20178:26#3
=A=L=X=
для игры написанной на лиспе такой графон очень даже ничего.
На PS1 помню что сцена не может иметь больше 1-2к полигонов.
=A=L=X=Постоялецwww31 окт. 20179:12#4
monobogdan
> На PS1 помню что сцена не может иметь больше 1-2к полигонов.

"Не может" тут скорее всего всё-таки "как правило не превышала", потому что как видно из рассказанного мной подхода к рендеру никакого принципиального ограничения в количестве и качестве треугольников в нём не присутствует - может просто начать тормозить, но не более того. В сущности треугольники даже не хранятся в обозначенной VRAM - они на лету скармливаются видеочипу через DMA произвольным списком, причём количество заходов не ограничено ничем.
Вот, для контраста, в Nintendo DS, насколько я читал, есть выделенный буфер под вершины в видеопамяти и его размер действительно поэтому строго диктует количество полигонов на кадр. Тут же видимо речь не более чем о гладкости графона - это уже баланс между филлрейтом и количество поликов, может быть достаточно индивидуальной штукой.

Правка: 31 окт. 2017 9:13

BUzerУчастникwww31 окт. 201713:55#5
=A=L=X=
Это что получается, каждая игра под соньку должна была реализовать свой алгоритм сортировки полигонов? Аппаратного подспорья там совсем никакого для этого не было?
0iStalkerМодераторwww31 окт. 201714:07#6
=A=L=X=
> она же - PSX)

Откройте уже тайну, почему ?

=A=L=X=Постоялецwww31 окт. 201714:44#7
0iStalker
> Откройте уже тайну, почему ?

Если склероз мне не изменяет, то то ли самсунг то ли филипс выпустил медиакомбайн из TV-приставки с интегрированной PS1 и вот она то и называлась PSX. Почему прилипло ко всем - х/з, может эта модель стала очень популярной где, не знаю. Причём этот же фокус потом проделали и с PS2 и в таком виде её тоже начали так же называть. Хотя тут аналогии очень прямые - у PS2 изначально была аппаратная совместимость с PS1.

BUzer
> Это что получается, каждая игра под соньку должна была реализовать свой
> алгоритм сортировки полигонов? Аппаратного подспорья там совсем никакого для
> этого не было?

Иногда можно встретить именно такое утверждение - что мол в PS1 было аппаратное подспорье для сортировки полигонов. И я даже знаю почему, но не согласен с такой постановкой вопроса. Я даже не стал упоминать эту мелочь в общем тексте.
Дело тут как раз в способности DMA-канала считывать буфера команд организованные в однонаправленный список. Еще один DMA-канал может аппаратно создать массив из таких списков нулевой длины. Аппаратно. Каждый i-ый в качестве следующего ссылается на (i+1)-ый и не содержит данных (нулевая длина буфера команд). Вот эту "мегафичу" и описывают (в том числе в документации по ссылке) иногда как "подспорье". Опять же - почему - объяснять долго, и по мне это не выдерживает никакой критики, поэтому я и не упоминал об этом и сейчас рассусоливать-время тратить не вижу смысла.

innuendoПостоялецwww31 окт. 201721:41#8
=A=L=X=
well done
lookidПостоялецwww31 окт. 201722:30#9
Тема очень интересна. Особенно про ps3/4 xbox360/one. Чего это там было такое дикое, что так дико все подикому угорали. Что-то типа "Как мы портировали с ПК на Консоли"
=A=L=X=Постоялецwww1 ноя. 201710:35#10
lookid
> Особенно про ps3/4 xbox360/one

Ну PS4 и XBox One архитектурно почти те же персоналки, только что операционки другие. Причём на боксе даже API - DirectX, так что о радикальных отличиях говорить не приходится.
Что на PS4 - уже не знаю, но по моим глубоким подозрениям именно после работы с сонькой ATI и начала собственную иницативу Mantle, которая ныне вылилась на персоналках в Vulkan API.
ATI конечно выгодно устроилась - стала поставщиком объединённого процессорно-графического чипа и Майкрософту и Сони - так что ядро консолей не просто похожее, а отличается чуть ли не только серийными номерами (ну и частотами там и т.п.). Такими темпами дойдёт до того, что отличаться консоли будут только наклейками и предустановленной операционкой в магазине, лол.

А вот PS3/XBox One это конечно отдельная песня, но до неё думаю нескоро дойду.

Правка: 1 ноя. 2017 10:37

return [](){};Участникwww1 ноя. 201712:09#11
Пиши исчо!
Про хардварный order independent transparency на dreamcast

Правка: 1 ноя. 2017 12:10

=A=L=X=Постоялецwww1 ноя. 201712:40#12
return [](){};
> Про хардварный order independent transparency на dreamcast

Действительно забавно, даже не знал таких деталей.

=A=L=X=Постоялецwww1 ноя. 201714:02#13
О, нашёл в сети руководство по программированию Nintendo 64 от самой Nintendo - официалка, поэтому следующий сжатый обзор наверное про неё напишу. В принципе это конкурент как раз PS1 вышедший двумя годами позднее, поэтому можно будет сравнивать и проводить параллели.
По хорошему если после описать еще Sega Saturn, то все основные конкуренты пятого поколения будут охвачены, остальные уже меркнут на их фоне по числу продаж.
lookidПостоялецwww2 ноя. 20170:02#14
Ты будешь писать? Такая тема интересная.
Страницы: 1 2 3 4 5 Следующая »

/ Форум / Флейм / Железо

2001—2017 © GameDev.ru — Разработка игр