diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index 2c195ea..bb65efa 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -41,12 +41,12 @@ "state": { "type": "markdown", "state": { - "file": "PERSONAL PROJECTS/LZSS C++ Lib.md", + "file": "PERSONAL PROJECTS/PS1 Gpu-DMA.md", "mode": "source", "source": false }, "icon": "lucide-file", - "title": "LZSS C++ Lib" + "title": "PS1 Gpu-DMA" } } ], @@ -207,8 +207,9 @@ }, "active": "dd912cc876184c4f", "lastOpenFiles": [ - "WORK & PROJECTS/Mol/Ideas/Все идеи для Моли.md", "PERSONAL PROJECTS/LZSS C++ Lib.md", + "PERSONAL PROJECTS/PS1 Gpu-DMA.md", + "WORK & PROJECTS/Mol/Ideas/Все идеи для Моли.md", "WORK & PROJECTS/Mol/Серверы/mail.mol-soft.ru.md", "WORK & PROJECTS/Mol/Документы для ТЗ ЛИМС/СМК/КУ_Чек_лист_10_ошибок_УД_скачивание.pdf", "WORK & PROJECTS/Mol/Документы для ТЗ ЛИМС/СМК", @@ -250,7 +251,6 @@ "WORK & PROJECTS/Mol/Серверы/Alfa cloud prod_canvas2doc-data/newdoc-node_b9a89b6c704bbab9_fromCanvas.md", "WORK & PROJECTS/Mol/Серверы/Alfa cloud prod_canvas2doc-data/newdoc-node_ac17a82fee50447b_fromCanvas.md", "WORK & PROJECTS/Mol/Серверы/Alfa cloud prod_canvas2doc-data/newdoc-node_9cf121717dbde800_fromCanvas.md", - "WORK & PROJECTS/Mol/Серверы/Alfa cloud prod_canvas2doc-data/newdoc-node_9ac7fb4c1839d1c1_fromCanvas.md", "WORK & PROJECTS/Mol/Серверы/Alfa cloud prod.canvas", "PERSONAL PROJECTS/P2EP/cdRead.canvas", "P2EP/cdRead.canvas", diff --git a/PERSONAL PROJECTS/PS1 Gpu-DMA.md b/PERSONAL PROJECTS/PS1 Gpu-DMA.md new file mode 100644 index 0000000..355b3dd --- /dev/null +++ b/PERSONAL PROJECTS/PS1 Gpu-DMA.md @@ -0,0 +1,134 @@ +В PlayStation 1 (PS1) передача видеокоманд через DMA в GPU — это ключевой механизм для эффективного рендеринга. Разберём процесс детально, включая работу с памятью. + +--- + +## **1. Как передаются видеокоманды через DMA?** +GPU PS1 не имеет собственного набора инструкций — он выполняет **примитивные команды**, переданные CPU. Эти команды организуются в **цепочку DMA** (Display List), которая указывает, что и как рисовать. + +### **1.1. Структура цепочки команд** +Каждая команда в цепочке состоит из: +- **Слова-заголовка** (указывает тип примитива: полигон, спрайт, настройка и т. д.). +- **Данных** (координаты, цвета, текстуры). + +Пример команды для отрисовки треугольника: +```c +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. + +**Код на ассемблере (пример):** +```asm +; Запись адреса цепочки в 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** +```c +// 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](https://github.com/Lameguy64/psn00bsdk)). \ No newline at end of file