Việc sửa đổi một kết cấu (vẽ trên đó) có được coi là thay đổi trạng thái của cải không?


11

Quy ước trong đồ họa là thực hiện ít thay đổi trạng thái tốt hơn so với thực hiện nhiều thay đổi trạng thái (chuyển đổi shader, bộ đệm liên kết, kết cấu ràng buộc, v.v.). Đối với kết cấu, sẽ nhanh hơn khi kết xuất nhiều đa giác bằng cách sử dụng một tập bản đồ (để hiển thị các họa tiết / văn bản) hơn là liên kết riêng một kết cấu mới cho mỗi đa giác.

Điều này có đúng không nếu tôi liên tục vẽ lên một kết cấu thông qua glTexSubImage2D? Tôi có một luồng dữ liệu đến (qua một mạng) trải qua quá trình xử lý và sau đó được vẽ thành một hàng một kết cấu tại một thời điểm. Dữ liệu được trình bày trực quan trong một cuộn vô tận.

Tôi có nên vẽ một họa tiết trên một hình chữ nhật lớn hơn không (cuộn dữ liệu đã vẽ vào chế độ xem)? Ý tưởng ở đây là tôi sẽ có một (hoặc hai) họa tiết bị ràng buộc tại bất kỳ thời điểm nào trong khi tôi chỉ tiếp tục vẽ lên nó.

Hoặc tôi nên vẽ nhiều hình chữ nhật nhỏ (chỉ tiết lộ hình chữ nhật khi vẽ xong)? Tôi giả sử tôi sẽ liên kết một kết cấu trên mỗi hình chữ nhật.

Câu trả lời:


11

Cập nhật một vùng bộ nhớ trong thiết bị đồ họa (kết cấu, bộ đệm và tương tự) không hoàn toàn giống như thay đổi trạng thái kết xuất.

Điều làm cho một thay đổi trạng thái kết xuất trở nên đắt đỏ là khối lượng công việc mà trình điều khiển phải làm để xác thực (các) trạng thái mới và sắp xếp lại đường ống. Điều này rất có thể cũng sẽ phải chịu một số đồng bộ hóa giữa CPU và thiết bị đồ họa. Tuy nhiên, lượng dữ liệu được truyền giữa các thiết bị nên nhỏ để thay đổi trạng thái (có thể chỉ là một vài lệnh).

Mặt khác, đối với cập nhật kết cấu / bộ đệm, chi phí chính nằm ở chính việc truyền dữ liệu. Về lý thuyết, trừ khi bạn đọc dữ liệu kết cấu trở lại CPU sau khi cập nhật, sẽ không có đồng bộ hóa hoặc quầy hàng đường ống. Tuy nhiên, một khía cạnh khác cần được xem xét: chi phí API. Ngay cả khi lượng dữ liệu bạn gửi đến thiết bị đồ họa nhỏ, nếu bạn làm điều đó thường xuyên, cuối cùng, chi phí giao tiếp với trình điều khiển / thiết bị sẽ trở nên lớn hơn sau đó chi phí truyền dữ liệu. Đó là một lý do khác tại sao việc tạo khối rất quan trọng khi tối ưu hóa trình kết xuất.

Vì vậy, trong trường hợp của bạn, cách tiếp cận tốt nhất, đối với tôi, sẽ là giữ một bản sao bộ nhớ hệ thống của kết cấu mà bạn cập nhật mỗi khi có dữ liệu mới. Đặt cờ bẩn và hợp nhất càng nhiều cập nhật càng tốt thành một glTexSubImagecho toàn bộ kết cấu (hoặc một phần lớn liên tiếp của nó). Bạn cũng có thể chơi với Đối tượng bộ đệm Pixel và cố gắng thực hiện truyền dữ liệu không đồng bộ để giảm các quầy hàng đường ống càng nhiều càng tốt. Nếu bạn có thể thực hiện một số loại bộ đệm đôi, thì bạn có thể ghi vào một bản sao của kết cấu trong khi bản kia đang được kết xuất. Hướng dẫn nàykhám phá kịch bản đó. Đó là cách tiếp cận trực quan của tôi, tôi sẽ cố gắng giảm số lượng lệnh gọi API và "bó" các bản cập nhật kết cấu. Điều đó đang được nói, điều này rất suy đoán, và bạn phải lập hồ sơ và so sánh nó với các phương pháp khác, như thực hiện một số cập nhật nhỏ, để biết chắc chắn đâu là hiệu quả nhất trong trường hợp sử dụng của bạn.

Là một lưu ý phụ, bài thuyết trình này của NVidia cũng có liên quan và cung cấp nhiều thông tin chi tiết tốt: Tiếp cận chi tiết về trình điều khiển Zero trong OpenGL .


5
Tôi không biết chắc chắn, nhưng tôi chắc chắn sẽ nghi ngờ rằng glTexSubImage trên một kết cấu đã được hiển thị trong khung cuối cùng hoặc hai sẽ làm chậm đường ống, vì trình điều khiển PC thường cố gắng đệm một hoặc hai khung, và không có khả năng muốn tạo bản sao của toàn bộ kết cấu vì một bản cập nhật nhỏ. Vì vậy, tôi mong muốn bộ đệm đôi hoặc gấp ba kết cấu (hoặc đối tượng bộ đệm pixel) sẽ được yêu cầu để có hiệu suất tối đa.
John Calsbeek
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.