Files
SergObsidian/PERSONAL PROJECTS/PS1 DOCS/PS1 Gpu-DMA.md
2025-04-18 23:10:56 +05:00

7.0 KiB
Raw Blame History

В PlayStation 1 (PS1) передача видеокоманд через DMA в GPU — это ключевой механизм для эффективного рендеринга. Разберём процесс детально, включая работу с памятью.


1. Как передаются видеокоманды через DMA?

GPU PS1 не имеет собственного набора инструкций — он выполняет примитивные команды, переданные CPU. Эти команды организуются в цепочку DMA (Display List), которая указывает, что и как рисовать.

1.1. Структура цепочки команд

Каждая команда в цепочке состоит из:

  • Слова-заголовка (указывает тип примитива: полигон, спрайт, настройка и т. д.).
  • Данных (координаты, цвета, текстуры).

Пример команды для отрисовки треугольника:

typedef struct {
    uint32_t header;  // Тип примитива (например, POLY_F3)
    uint16_t x1, y1;  // Координаты
    uint16_t x2, y2;
    uint16_t x3, y3;
    uint8_t r, g, b;  // Цвет
} GPUPrimitive;

1.2. Передача через DMA

  1. CPU формирует цепочку команд в основной RAM (например, массив структур).
  2. Адрес этой цепочки передаётся в GPU через DMA.
    • Используется порт GP0 (для команд) и GP1 (для управления).
  3. DMA-контроллер (канал GPU) копирует данные из RAM в GPU.

Код на ассемблере (пример):

; Запись адреса цепочки в DMA
li a0, 0x1F8010A0    ; Адрес регистра DMA_GPU (канал 2)
la a1, command_list  ; Адрес цепочки команд в RAM
sw a1, 0(a0)         ; Записываем адрес

; Настройка DMA
li a0, 0x1F8010A4
li a1, 0x01000200    ; Размер блока + флаги (например, 0x200 байт)
sw a1, 0(a0)

; Запуск DMA
li a0, 0x1F8010A8
li a1, 0x01000001    ; Включить DMA
sw a1, 0(a0)

2. Как GPU читает команды?

2.1. Отсутствие собственной памяти для команд

У GPU нет отдельной памяти для хранения команд (в отличие от современных GPU). Он:

  1. Читает команды напрямую из основной RAM через DMA.
  2. Интерпретирует их "на лету" (как потоковый процессор).

2.2. Роль FIFO-буфера

GPU имеет маленький FIFO-буфер (32 слова):

  • DMA заполняет этот буфер, пока GPU читает данные.
  • Если буфер переполняется, DMA приостанавливается.

3. Где хранятся данные?

3.1. Основная RAM (2 МБ)

  • Цепочки команд хранятся здесь.
  • Текстуры тоже могут быть в RAM (но чаще копируются в VRAM).

3.2. Видеопамять (VRAM, 1 МБ)

  • Кадровый буфер (Frame Buffer) — хранит пиксели.
  • Текстуры — загружаются сюда для быстрого доступа.
  • CLUT (Color Look-Up Table) — палитры для 8-битных текстур.

3.3. Как GPU обращается к данным?

  • Через DMA: Текстуры/данные копируются из RAM в VRAM перед рендерингом.
  • Прямой доступ: GPU читает VRAM при отрисовке (например, текстуры).

4. Пример: полный цикл работы

  1. Подготовка:
    • CPU создаёт в RAM массив команд (например, DrawPolygon, LoadTexture).
    • Текстуры копируются в VRAM через GP0 или DMA.
  2. Запуск рендеринга:
    • CPU отправляет адрес цепочки в DMA-контроллер GPU.
    • DMA копирует команды из RAM в FIFO GPU.
    • GPU выполняет команды, рисуя в кадровый буфер (VRAM).
  3. Вывод изображения:
    • Видеоконтроллер выводит кадр из VRAM на экран.

5. Критические нюансы

  1. Синхронизация:
    • Если GPU занят, DMA приостанавливается (проверяется через статусный регистр GP1).
  2. Оптимизация:
    • Связные списки команд (OT — Ordering Table) позволяют сортировать примитивы.
  3. Ограничения:
    • DMA может работать только с выровненными данными (адреса, кратные 4).
    • Переполнение FIFO приводит к "пропущенным кадрам".

6. Псевдокод для работы с DMA и GPU

// 1. Загрузка текстуры в VRAM
void LoadTexture(uint16_t x, uint16_t y, void* tex_data) {
    GP0_SendCommand(0xA0000000 | (y << 11) | x);  // Адрес в VRAM
    GP0_SendCommand(0x10000000 | (width * height)); // Размер
    DMA_Start(GPU_CHANNEL, tex_data, size);        // Копируем через DMA
}

// 2. Формирование цепочки команд
struct CommandList {
    uint32_t prim_header;
    uint32_t data[10];
} __attribute__((aligned(4)));  // Выравнивание для DMA

// 3. Запуск рендеринга
void DrawFrame() {
    CommandList list = { ... };
    DMA_Start(GPU_CHANNEL, &list, sizeof(list));
    GPU_TriggerDMA();  // Запуск выполнения
}

Итог

  • DMA в PS1 передаёт адрес цепочки команд из RAM в GPU.
  • GPU не имеет своей памяти для команд — читает их напрямую из RAM через DMA/FIFO.
  • VRAM используется только для хранения текстур и кадрового буфера.
  • Оптимизация DMA-передач критична для производительности.

Это объясняет, почему в демосценах PS1 так важны оптимизированные DMA-цепочки и ручное управление памятью. Для глубокого понимания изучите документацию PsyQ SDK или исходники open-source движков (например, PSn00bSDK).