- vừa được xem lúc

GPU vẽ lên màn hình như thế nào?

0 0 18

Người đăng: Phuong Le

Theo Viblo Asia

Phuongne, Th3 07, 2020

Load dữ liệu vào RAM & VRAM

RAM: bộ nhớ tạm thời cạnh CPU, truy cập rất nhanh
VRAM: bộ nhớ tạm thời cạnh GPU, truy cập rất nhanh

Đầu tiên các dữ liệu cần vẽ (3D) như vertex, texture, meshes… sẽ được load từ disk (SSD hay HDD) sang system memory (RAM) để CPU có thể truy cập nhanh hơn, sau đó lại được load từ RAM sang bộ truy cập nhanh của GPU là VRAM, Bởi GPU truy cập dữ liệu ở VRAM nhanh hơn so với dữ liệu ở disk và RAM.

Copy dữ liệu vào VRAM giúp truy cập nhanh hơn

Sau khi đã load dữ liệu về texture vào VRAM, nếu CPU không cần sử dụng dữ liệu đó thì nó sẽ bị xoá đi và phải chắc chắn rằng dữ liệu sẽ không được CPU sử dụng lại trong một thời gian sắp tới, bởi việc load từ disk sang RAM cũng ngốn kha khá performance.

Còn dữ liệu về meshes thường lưu trữ lâu hơn trong RAM nếu đang còn sử dụng tới để phát hiện, xử lý va chạm…

2deleteDataInRam.gif

Xóa dữ liệu CPU không sử dụng lại nữa trong RAM

“Nếu GPU xử lý nhanh và thời gian truy cập VRAM chậm thì sao?”

Dữ liệu đã sẵn sàng ở trong VRAM, nếu thời gian GPU truy cập VRAM không đủ nhanh, thì GPU còn có một bộ nhớ nhỏ đặt trực tiếp trong nó nữa gọi là L2 Cache, keyword của nó là “on-chip caches”. Thậm chí nếu vẫn không đủ nhanh thì GPU có thể truy cập vào một bộ nhớ nằm sát ngay cạnh các cores của GPU là L1 Cache

Tuy nhiên size của 2 cái bộ nhớ trên rất nhỏ, ví dụ L2 Cache của NVIDIA là GM204 chỉ có 2048 KB, L1 Cache như GM204 chỉ có 384 KB

image.png

GPU-Cached Memory

“Còn bộ nhớ nào GPU sử dụng nữa không?”

Thật ra chúng ta còn bộ nhớ GPU dùng để lấy dữ liệu và xuất dữ liệu đã xử lý gọi là Register, GPU sẽ lấy dữ liệu từ Register, xử lý, rồi trả kết quả lại cho Register. Developer thường không cần quan tâm tới các bộ nhớ này.

ezgif.com-optimize.gif

L1 L2 Register

“Vậy làm thế nào GPU có thể vẽ các dữ liệu đã nhận được từ CPU lên màn hình?”

Sau khi GPU đã có vertex, meshes hay texture trong tay, CPU sẽ định nghĩa một loạt các thông tin cần phải xử lý cho meshes gọi là Render State như ánh sáng như nào, độ trong suốt như nào, vertex nằm ở đâu,… vân vân và mây mây

Render State và SetPass Call

Render State là các định nghĩa thông tin về cách hiển thị một meshes như mình nói ở trên: lighting (ánh sáng), vertex (đỉnh), material, lighting, transparency (độ trong suốt),… Các vật thể mà CPU nhờ GPU render đều sẽ dựa trên các thông tin trên, có thể nhiều meshes cùng chia sẻ một setting với nhau, kỹ thuật kết hợp vẽ các meshes với cùng một setting hay một RenderState nhằm tối ưu thời gian gọi là batching.

3renderstate.gif

Render State

Khi đã có Render State, CPU sẽ gọi tới GPU cập nhật setting bằng lệnh SetPass Call (cách gọi khác là RenderState Change, RenderState Call,…), sau đó nhờ GPU vẽ một mesh nào đó bằng một lệnh gọi là Draw Call.

Ví dụ thứ tự như này: SetPass Call: Đỏ -> Draw Call: Hình tam giác -> Draw Call: Hình chữ nhật -> SetPass Call: vàng -> Draw Call: Hình vuông ->…
Thì hình tam giác và hình chữ nhật chung setting là đỏ, hình vuông có setting là vàng, kỹ thuật gộp setting hình tam giác và hình chữ nhật là batching.

Draw Call

Một Draw Call không gì khác hơn là một lệnh của CPU gửi tới GPU nhờ vẽ MỘT mesh, Draw Call chỉ chứa một dữ liệu duy nhất là mesh cần vẽ, không chứa bất kỳ một thông tin gì về vertex, texture, color, shader,… gì cả, GPU sẽ vẽ mesh đó bằng setting (Render State) của SetPass Call gần nhất (xem lại ví dụ ở Render State). Tất nhiên là mesh cần vẽ đã nằm trong VRAM (hoặc bộ nhớ hỗ trợ khác)

4cpu_calls_gpu.gif

CPU gửi draw call tới GPU

Sau khi nhận lệnh từ CPU, GPU sẽ bắt đầu vẽ một mesh lên màn hình dựa trên các thông tin trong Render State cũng như dữ liệu trong VRAM, quá trình vẽ lên bao gồm một loạt các sự kiện diễn ra liên tục, quá trình này được gọi là Render Pipeline.

Render Pipeline

Sau khi GPU đã có trong tay các thông tin cần có bao gồm một số dữ liệu như: vertices (các đỉnh), textures,…

GPU sẽ phải tạo một mesh (khối) dựa trên các vertices (đỉnh) nhận được bằng các triangle (tam giác = 3 đỉnh), định nghĩa ánh sáng cho mesh hay cách mesh phản ứng với ánh sáng, vẽ mesh (khối) từ không gian 3D sang không gian 2D (màn hình)…

Tất nhiên công việc của GPU không đơn giản như vậy mà bao gồm rất nhiều task nhỏ, cùng rất rất nhiều các tính toán cho vertices và pixels. Ngày nay, GPU rất phát triển vì vậy các công việc này thường được xử lý một cách song song.

Thông thường, CPU hiện nay có 6-8 cores, trong khi đó GPU lại có từ hàng trăm đến hàng ngàn cores (không phức tạp bằng cpu-core), sau đây là một vài thông tin.

  • GTX 1050 có 640 cores trong khi GTX-1050Ti là 768 cores
  • GTX 1060 3GB: 1152 cores và 1280 cores cho phiên bản 6GB
  • GTX 1070 có 1920 cores
  • GTX 1080 có 2560 cores (1080 Ti là 3584 cores)

pipeline_overview_multicore-1.gif

Simple Render Pipeline

“Thế trong lúc GPU đang xử lý thì CPU ngồi chơi hả?”

CPU và GPU sẽ xử lý song song và giao tiếp với nhau thông qua một danh sách (list) gọi là Command Buffer theo nguyên tắc FIFO – First In First Out, giống với cấu trúc Queue.
CPU sẽ đưa vào lệnh, GPU nhặt lệnh và thực hiện, chờ lệnh tiếp theo hoặc lấy lệnh tiếp theo có trong buffer.

Trong trường hợp CPU xử lý quá chậm, GPU lại quá nhanh sẽ gây ra tình trạng bottle-neck (nghẽn cổ chai) mà rất nhiều player hay gamer gặp phải.

Command Buffer

Buffer này giúp CPU và GPU giao tiếp với nhau và hoạt động một cách song song, nếu CPU muốn thay đổi RenderState bằng lệnh SetPass Call hoặc vẽ mesh bằng lệnh DrawCall thì CPU sẽ đẩy vào trong Command Buffer

Sau khi xử lý xong công việc hiện tại, GPU lấy lệnh tiếp theo (theo nguyên tắc FIFO) trong buffer (nếu có) và thực thi.

commandbuffer_communication.gif

CPU giao tiếp GPU thông qua Command Buffer

Trong Unity3D, module UnityEngine.Rendering cũng có một class CommandBuffer hoạt động tương tự, chứa danh sách các lệnh mà graphics cần thực thi, tham khảo ở CommandBuffer

Claims

Bài viết được đăng vào 2020, chỉ mang tính chất tham khảo các bạn nhé 😉

Tạm kết và nguồn tham khảo

Nguồn tham khảo:
https://simonschreibt.de/gat/renderhell-book1/
https://simonschreibt.de/

Bình luận

Bài viết tương tự

- vừa được xem lúc

Tạo setting game trên inspector.

. Chào các bạn,. Hôm nay chúng ta sẽ cùng tạo 1 setting/config cho game trên inspector nhé. Câu trả lời đó là khi chúng ta cần 1 cái gì đó để thao tác trong editor, trực quan nhất, không cần sửa code để cập nhật dữ liệu.... Và hẳn các bạn cũng từng làm việc với những value trên inspector rồi, ví dụ

0 0 22

- vừa được xem lúc

Hướng dẫn đưa nhân vật từ Mixamo vào demo.

. Chào các bạn. Bài này chúng ta chỉ tìm hiểu cách để lấy model, animation về, setting sao cho nó chạy được trong Unity để làm demo là ngon rồi nhé . Bước 1: Đăng nhập. Hãy tạo tài khoản nếu các bạn chưa có.

0 0 25

- vừa được xem lúc

Cơ bản về Rigidbody trong Unity3D

Phuong Le at 31-10-2019 - phuongne. Bài viết từ 2019 nên chỉ có giá trị tham khảo bạn nhé . . Rigidbody là gì.

0 0 18

- vừa được xem lúc

Một số folder đặc biệt trong Unity

Phuong Le 2019 - phuongne. Bài viết từ 2019 nên chỉ có giá trị tham khảo bạn nhé .

0 0 15

- vừa được xem lúc

Coroutine trong Unity là gì? Có liên quan tới Threads hay không?

Phuongne, Th11 17, 2019. Sơ qua một chút về Coroutine và StartCoroutine(.

0 0 11

- vừa được xem lúc

So sánh nhẹ Coroutine và Invoke

Phuongne - 31-10-2019. . Roài, đây sẽ là một bài viết ngắn nên mình đi vào chi tiết luôn, khởi mở đầu giới thiệu dài dòng nhá anh em. Coroutine với Invoke là gì.

0 0 17