Những cuộc gọi DirectX11 nào thực sự gửi dữ liệu tới GPU?


7

Tôi đang cố gắng học lập trình đồ họa và DirectX11.

Tôi đang cố gắng học cách giảm thiểu việc chuyển CPU-GPU và lập trình đồ họa nói chung.
Tôi có một câu hỏi mà tôi không thể tự trả lời từ các tài nguyên trực tuyến:

Phương thức D3D nào thực sự gửi dữ liệu tới GPU (và, tương tự, đối với lưới tĩnh, TẤT CẢ dữ liệu đỉnh được truyền đến GPU mỗi khung hình hay chỉ một lần)?

Mã sau:
(đơn giản hóa cho stackexchange)

Trong lớp "lưới" của tôi, tôi có một bộ đệm đỉnh:

ID3D11Buffer *m_pVBuffer;

Trong hàm tạo của lưới của tôi, tôi đặt một số đỉnh cho bộ đệm đỉnh:

D3D11_MAPPED_SUBRESOURCE ms;
devcon->Map(m_pVBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms);
memcpy(ms.pData, &vertices[0], sizeof(VERTEX) * vertices.size());
devcon->Unmap(m_pVBuffer, NULL);

Sau đó, trong phương thức "kết xuất" của lưới của tôi, tôi làm điều này:

UINT stride = sizeof(VERTEX);
UINT offset = 0;
devcon->IASetVertexBuffers(0, 1, &m_pVBuffer, &stride, &offset);
devcon->IASetIndexBuffer(m_pIBuffer, DXGI_FORMAT_R32_UINT, 0);
devcon->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
devcon->DrawIndexed(m_num_indices, 0, 0);

Nhắc lại: Dữ liệu được tải lên GPU khi I Map, memcpy và Unmap bộ đệm đỉnh, hay nó được tải lên mọi khung hình, khi tôi gọi IASetVertexBuffers?

Câu trả lời:


7

Đây là một câu hỏi khó vì bạn không có toàn quyền kiểm soát liệu bộ đệm đỉnh được lưu trữ trong VRAM hay RAM chính. Trình điều khiển đưa ra quyết định cho bạn dựa trên các cờ truy cập sử dụng và CPU được chỉ định khi bạn tạo bộ đệm đỉnh.

Nói chung, bộ đệm với cách sử dụng mặc định và không thay đổi sẽ được lưu trữ trong VRAM; những người có sử dụng dàn sẽ được lưu trữ trong RAM chính; và những người có cách sử dụng năng động có thể ở một trong hai nơi. Tuy nhiên, nếu không đủ VRAM, trình điều khiển sẽ lưu trữ tài nguyên trong RAM chính dưới dạng dự phòng.

Nếu bộ đệm kết thúc trong VRAM, dữ liệu sẽ đi qua bus hệ thống (kết nối CPU và GPU) bất cứ khi nào CPU cập nhật bộ đệm (nghĩa là khi bạn thực hiện cặp Map / Unmap). Nếu nằm trong RAM chính, GPU sẽ đọc dữ liệu trên bus hệ thống mỗi khi bạn sử dụng bộ đệm đó để kết xuất.

Vì vậy, thông thường, đối với các lưới tĩnh, bạn sẽ sử dụng cách sử dụng không thay đổi và bộ đệm sẽ được lưu trữ trong VRAM, do đó không có chuyển hệ thống bus bổ sung sau khi thiết lập ban đầu. Đối với bộ đệm đỉnh động (đối với các hạt hoặc tương tự), bạn sẽ sử dụng mức sử dụng động và dữ liệu sẽ đi qua bus một lần mỗi khung hình - nếu là trong VRAM, bus sẽ được sử dụng để CPU ghi vào nó và nếu Trong RAM chính, bus sẽ được sử dụng để GPU đọc nó.


Các bài kiểm tra tôi chạy xác nhận câu trả lời này. Khi tôi kết xuất nhiều vật thể, sẽ có sự chậm lại ban đầu trong vài giây đầu tiên nhưng sau đó tốc độ khung hình tăng lên. Cho rằng tôi làm điều tương tự mọi khung hình, điều này phải là vì ít nhất một phần của bộ đệm được "lưu trữ" trong VRAM. Vì vậy, câu trả lời là "Nó sẽ chỉ được tải lên một lần. Có lẽ. Bạn không nên tin vào điều đó."
x10

0

Câu trả lời sẽ phụ thuộc vào bất kỳ thế hệ cụ thể nào của trình điều khiển phần cứng được tối ưu hóa cao cảm thấy như thế nào, nghĩa là không có câu trả lời chung cho bạn.

Thêm vào sự phức tạp đó, thực tế là các trình điều khiển đang hiển thị các khung 1-N phía sau so với những gì bạn hiện đang bảo họ hiển thị vì thẻ 3D được tuần tự hóa cao và song song và được lưu trữ và hoạt động không đồng bộ để hoàn thành công việc.

Nếu bạn chỉ đang học thì thông tin quan trọng cần biết là các điểm trình tự để chuẩn bị kết xuất: mô tả dữ liệu, sao chép dữ liệu, cho người lái xe biết dữ liệu nào sẽ sử dụng, sau đó tắt kết xuất. Và không phải những gì xảy ra khi, đó thực sự là một lỗ thỏ rất sâu.


0

Sự hiểu biết của tôi, chủ yếu dựa trên việc đọc này là trình điều khiển nói chung sẽ không gửi bất kỳ tài nguyên nào tới bộ nhớ video, cho đến khi tài nguyên được sử dụng trong lệnh gọi rút thăm.

Điều đó có nghĩa là nhà xây dựng có thể sẽ không chạm vào phần cứng GPU, và phương thức kết xuất sẽ. Tuy nhiên, ngay cả lệnh gọi Draw Indexed () có thể sẽ không được chuyển đến phần cứng ngay lập tức vì CPU hiệu quả hơn để đệm danh sách lớn các lệnh GPU.

Trình điều khiển cũng có thể dỡ dữ liệu khỏi bộ nhớ GPU khi hết (giả sử nó có bản sao của nó trong RAM chính). Trong trường hợp cực đoan, điều này có thể xảy ra nhiều hơn một lần trên mỗi khung.

Tất nhiên tất cả những điều này được trình điều khiển ẩn khỏi trình lập trình, vì vậy bạn không thể dựa vào nó như thế - trình điều khiển thay đổi liên tục.


Rất có khả năng nó sẽ không thực hiện cuộc gọi rút thăm - cuộc gọi rút thăm chỉ đến bộ đệm lệnh do trình điều khiển quản lý và được xóa trong thời gian ngọt ngào của trình điều khiển, có thể là bất kỳ khoảng thời gian nào sau đó.
Maximus Minimus
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.