Làm cách nào để sử dụng UpdateSubresource và Map / Unmap?


8

Từ những gì tôi hiểu (từ việc đọc các trang khác nhau), có 2 cách để cập nhật bộ đệm:

  1. UpdateSubresource()(khi bộ đệm được tạo với DEFAULTviệc sử dụng)
  2. Map(), sao chép dữ liệu mới, Unmap()(khi bộ đệm được tạo với DYNAMICviệc sử dụng)

Trong trường hợp đầu tiên tôi chỉ gọi hàm này (không có gì nữa)? Bởi vì tôi đã thấy mọi người nói rằng họ ánh xạ bộ đệm và sau đó cập nhật nguồn phụ, hoặc có thể tôi đã hiểu nhầm họ.

Ngoài ra còn có cách nào khác (nghi ngờ nó: P)? Tôi có hiểu mọi thứ một cách chính xác không?

Câu trả lời:


11

Có một bài thuyết trình hay về điều này: Đừng vứt bỏ tất cả: Quản lý bộ đệm hiệu quả của John McDonald tại NVIDIA. Nó bao gồm chủ đề khác nhau, nhưng về vấn đề câu hỏi của bạn, những lời khuyên chung là tạo ra vùng đệm với việc sử dụng năng động và sử dụng Map()với D3D11_MAP_WRITE_DISCARD, khi dữ liệu cần phải được cập nhật thường xuyên (như mỗi khung hình, hoặc nhiều lần mỗi khung hình). Điều này sẽ được sử dụng cho bộ đệm không đổi, bộ đệm đỉnh cho các hệ thống hạt và tương tự.

Theo bản trình bày, việc sử dụng mặc định / UpdateSubresource()phát sinh nhiều chi phí CPU hơn so với sử dụng động / Map(). Tuy nhiên, ông không khuyến nghị sử dụng mặc định / UpdateSubresource()cho dữ liệu chỉ cần cập nhật một lần trong một lúc, chẳng hạn như dữ liệu được truyền từ đĩa trong trò chơi thế giới mở.

Và có, trong trường hợp bạn sử dụng UpdateSubresource(), bạn sẽ tự sử dụng nó, không kết hợp với Map().


2
Kỳ lạ, cả hai bạn đã trả lời trong cùng một phút và đăng cùng một liên kết.
NPS

Trong một chủ đề khác, bạn đã viết: "Bạn không cần phải liên kết bộ đệm để cập nhật nó với UpdateSubresource. Thực tế, nó không nên bị ràng buộc khi bạn cập nhật nó". Điều này có nghĩa là tôi phải luôn hủy liên kết tất cả các bộ đệm trước khi cập nhật chúng? Nếu vậy, làm thế nào để tôi hủy liên kết một bộ đệm?
NPS

1
@NPS Trước hết, nó sẽ hoàn toàn không bị ràng buộc nếu bạn đã ràng buộc một cái gì đó khác ở vị trí của nó. Mặt khác, bạn có thể liên kết rõ ràng NULL để hủy liên kết bộ đệm. Chẳng hạn, bạn có thể thực hiện ID3D11ShaderResourceView * nullsrv = NULL; pCtx->PSSetShaderResources(0, 1, &nullsrv);để hủy kết cấu từ vị trí 0.
Nathan Reed

Tôi biết về cái ngầm nhưng cần cái rõ ràng, thx. Nhưng bạn đã không trả lời câu hỏi đầu tiên của tôi - tôi có phải làm điều này luôn cho tất cả các bộ đệm mà tôi dự định cập nhật không?
NPS

1
@NPS Lý tưởng nhất là bộ đệm không nên được sử dụng bởi GPU tại thời điểm bạn cập nhật nó trên CPU. Nhưng GPU và CPU chạy không đồng bộ, vì vậy điều này không dễ đảm bảo. Tôi sẽ nói đừng lo lắng về điều đó trừ khi bạn thấy đó là một vấn đề hiệu suất thực tế.
Nathan Reed

2

Họ có thể đã đề cập đến hành động thực tế là cập nhật tài nguyên chứ không phải gọi chức năng thực tế. Nói chung, UpdateSubResource nên được sử dụng cho các tài nguyên mặc định không phải là bản cập nhật thường xuyên (nghĩa là: không phải mọi khung. Trong trường hợp này, nhiều khả năng bộ đệm có thể được sao chép vào bộ đệm tạm thời có thể truy cập từ bộ đệm lệnh ( do điều kiện chủng tộc chẳng hạn). Nó cũng sẽ cho phép bạn cập nhật tài nguyên phụ (ví dụ về kết cấu).

Map / Unmap nên được sử dụng khi tài nguyên sẽ được cập nhật rất thường xuyên (tức là mọi khung hình), chẳng hạn như một số bộ đệm không đổi. Trường hợp phổ biến nhất là khi bạn ghi đè toàn bộ bộ đệm bằng WriteDiscard. Có một bài thuyết trình nVidia nơi họ giới thiệu thực hành này.

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.