Lợi thế của cơ chế truy cập trạng thái trực tiếp của OpenGL là gì?


11

Tôi đã đọc về Truy cập trạng thái trực tiếp OpenGL 4.5 (DSA) tại opengl.org và không chắc liệu tôi có làm đúng hay không.

Dường như ngụ ý rằng cách cũ kém hiệu quả hơn:

glBind(something)
glSetA(..)
glSetB(..)
glSetC(..)

hơn cách mới:

glSetA(something, ..)
glSetB(something, ..)
glSetC(something, ..)

Từ vẻ bề ngoài của nó, mỗi cái glSetphải bao gồm glBind(something)bên trong nó và nếu OpenGL vẫn là một máy trạng thái thì không thể tận dụng các thay đổi được truyền phát được áp dụng cho một something.

Vui lòng giải thích lý do đằng sau và lợi thế của DSA mới.

Câu trả lời:


21

Từ vẻ bề ngoài của nó, mỗi glset phải bao gồm glBind (thứ gì đó) bên trong nó

Không chính xác. Đó là cách khác, như được mô tả một số đoạn dưới đây.

Ngay cả khi đó là sự thật, hãy nhớ rằng các lệnh GL từ ứng dụng khách đến máy chủ GL (còn gọi là trình điều khiển) có rất nhiều công việc được gửi đi so với một cuộc gọi chức năng thông thường. Ngay cả khi chúng tôi cho rằng các hàm DSA chỉ là các hàm bao quanh các hàm hiện có, chúng là các hàm bao sống bên trong máy chủ GL và do đó có thể có ít hơn một chút chi phí.

nếu OpenGL vẫn là một máy trạng thái không thể tận dụng các thay đổi được truyền phát được áp dụng cho một thứ gì đó.

GPU không phải là máy trạng thái. Giao diện máy trạng thái GL là một mô phỏng bao bọc các phần bên trong trình điều khiển giống như DSA, không phải là cách khác.

Loại bỏ một lớp gói - một lớp yêu cầu số lượng cuộc gọi quá nhiều vào máy chủ GL - rõ ràng là một chiến thắng, ngay cả khi một cuộc gọi nhỏ.

Cách tiếp cận máy trạng thái cũng không có ý nghĩa gì khi xử lý nhiều luồng; GL vẫn còn khủng khiếp trong trường hợp sử dụng này, nhưng các trình điều khiển thường sử dụng các luồng phía sau hậu trường và một máy trạng thái đòi hỏi nhiều sự đồng bộ hóa luồng hoặc các thuật toán / cấu trúc song song thực sự lạ mắt để làm cho mọi thứ hoạt động đáng tin cậy.

Tiện ích mở rộng DSA tiếp tục diễn đạt hoạt động của nó theo các thay đổi trạng thái bởi vì cuối cùng, nó là một phần mở rộng cho một tài liệu dựa trên trạng thái hiện tại và không phải là một API hoàn toàn mới, do đó, nó phải sẵn sàng để cắm vào đặc tả GL hiện có ngôn ngữ và thuật ngữ tài liệu. Ngay cả khi ngôn ngữ hiện tại đó khá phù hợp với công việc của nó là API phần cứng đồ họa hiện đại.

Vui lòng giải thích lý do đằng sau và lợi thế của DSA mới.

Lý do lớn nhất là cách cũ là một nỗi đau. Điều này làm cho rất khó để kết hợp các thư viện với nhau mà mỗi thư mục có thể sửa đổi hoặc dựa vào trạng thái GL. Điều này gây khó khăn cho việc bọc API GL một cách hiệu quả theo kiểu hướng đối tượng hoặc chức năng do nguồn gốc quản lý trạng thái thủ tục sâu sắc của nó, khiến việc bọc API bằng nhiều ngôn ngữ không phải C khác nhau và cũng gây khó khăn cho việc cung cấp trình bao bọc thiết bị đồ họa hiệu quả OpenGL trừu tượng từ Direct3D.

Thứ hai là chi phí API máy nhà nước theo thủ tục, như được mô tả trước đây.

Thứ ba, các hàm DSA đã thay đổi ngữ nghĩa khi thích hợp từ các API cũ cho phép cải thiện hiệu quả. Chẳng hạn, những thứ trước đây có thể thay đổi được thực hiện bất biến, ví dụ, loại bỏ rất nhiều mã giữ sách khỏi máy chủ GL. Các cuộc gọi của ứng dụng có thể được gửi đến phần cứng hoặc được xác thực sớm hơn (hoặc trong thời trang song song hơn) khi máy chủ GL không phải xử lý các đối tượng có thể thay đổi.

-

Biện minh và giải thích bổ sung được đưa ra trong đặc tả phần mở rộng EXT_direct_state_access .

-

Thay đổi phần cứng có liên quan đến thiết kế API là khá nhiều.

Hãy nhớ rằng OpenGL có từ năm 1991. Phần cứng mục tiêu không phải là card đồ họa cấp tiêu dùng (những thứ không tồn tại) mà là các máy trạm CAD lớn và tương tự. Phần cứng của thời đại đó có phong bì hiệu suất rất khác so với ngày nay; đa luồng hiếm hơn, các bus bộ nhớ và CPU có ít khoảng cách về tốc độ và GPU đã làm được ít hơn so với kết xuất tam giác chức năng cố định.

Ngày càng có nhiều tính năng cố định được thêm vào. Các mô hình ánh sáng khác nhau, chế độ kết cấu, vv đều được thêm vào, mỗi cái cần một phần trạng thái riêng. Cách tiếp cận dựa trên trạng thái đơn giản có hiệu quả khi bạn có một số tiểu bang. Khi ngày càng có nhiều trạng thái được thêm vào, API bắt đầu bùng nổ tại các vỉa. API trở nên khó xử hơn nhưng không phân tán quá xa các chế độ phần cứng, vì chúng thực sự dựa trên rất nhiều công tắc trạng thái.

Sau đó, cùng đến phần cứng lập trình. Phần cứng ngày càng trở nên lập trình hơn, đến thời điểm hiện tại, phần cứng hỗ trợ một chút trạng thái, một số chương trình do người dùng cung cấp và rất nhiều bộ đệm. Tất cả trạng thái từ thời đại trước phải được mô phỏng, giống như tất cả các tính năng chức năng cố định của thời đại đó đang được các trình điều khiển mô phỏng.

Phần cứng cũng thay đổi để ngày càng song song. Điều này đòi hỏi phải thiết kế lại phần cứng khác làm cho trạng thái đồ họa thay đổi rất tốn kém. Phần cứng hoạt động trong các khối lớn của trạng thái bất biến. Do những thay đổi này, trình điều khiển không thể đơn giản áp dụng từng chút trạng thái mà người dùng đặt ngay lập tức mà phải tự động xử lý các thay đổi và áp dụng chúng khi cần.

Phần cứng hiện đại hoạt động hơn nữa từ mô hình OpenGL cổ điển. DSA là một thay đổi nhỏ cần thiết từ hơn 10 năm trước (ban đầu nó được hứa hẹn là một phần của OpenGL 3.0), tương tự như những gì D3D10 đã làm. Nhiều thay đổi phần cứng ở trên cần nhiều hơn chỉ là DSA để giữ cho OpenGL có liên quan, đó là lý do tại sao vẫn còn nhiều tiện ích mở rộng lớn thay đổi mạnh mẽ mô hình OpenGL . Sau đó, có toàn bộ API GLnext mới cộng với D3D12, Mantle, Metal, v.v. không phải là một trong số đó duy trì sự trừu tượng của máy trạng thái đã lỗi thời.


Cảm ơn câu trả lời. Vì vậy, có vẻ như trước đây một số máy trạng thái (không phải DSA) là một chiến thắng, nhưng đến một lúc nào đó, một số thứ đã thay đổi và bây giờ DSA là lợi thế. Bạn có thể làm sáng tỏ những gì đã thay đổi?
Kromster 4/2/2015

@KromStern: đã làm hết sức mình. Nếu bạn cần thêm chi tiết, ai đó hiểu biết hơn tôi sẽ phải cung cấp nó.
Sean Middleditch 4/2/2015

@KromStern Tôi đã thấy (từ nghiên cứu hạn chế của tôi về lịch sử) openGL chuyển sang các cuộc gọi rút ra ngày càng ít CPU trên mỗi khung hình; danh sách hiển thị (cho những gì chúng có giá trị), glDrawArrays (rút ra trong một cuộc gọi), VBO (tải lên GPU một lần), VAO (liên kết bộ đệm với thuộc tính một lần), đối tượng bộ đệm thống nhất (đặt đồng phục trong một lần). Có nhiều thứ tôi đang thiếu, tôi chắc chắn.
ratchet freak

@ratchetfreak: đủ vui, bây giờ chúng ta sẽ chuyển sang hướng khác. Các API / tiện ích mở rộng hiện đại tập trung vào việc tăng các lệnh gọi rút thăm của chúng tôi trên mỗi khung, chủ yếu bằng cách xóa tất cả trạng thái phải được đặt / gửi cho mỗi lệnh gọi rút thăm và thực hiện các lệnh gọi rút ra ít hơn là "chèn lệnh vẽ vào hàng đợi lệnh" đối với một lệnh lớn thiết lập trạng thái tĩnh và tài nguyên không ràng buộc. Oooh, không ràng buộc, tôi thậm chí quên đề cập đến phần đó trong câu trả lời của tôi.
Sean Middleditch 4/2/2015

@SeanMiddleditch Tôi nên đặt các cuộc gọi trên mỗi khung.
ratchet freak

1

Tổng quan biện minh cho nó bằng cách:

Mục đích của phần mở rộng này là làm cho nó trở nên hiệu quả hơn cho các thư viện để tránh làm phiền bộ chọn và trạng thái chốt. Phần mở rộng cũng cho phép sử dụng lệnh hiệu quả hơn bằng cách loại bỏ nhu cầu về các lệnh cập nhật bộ chọn.

Tôi nghĩ rằng "hiệu quả hơn" ở đây đề cập đến cả chi phí kế toán ít hơn cho các tác giả thư viện và dẫn đến hiệu suất cao hơn. Với API hiện tại, để "cư xử tốt", bạn cần truy vấn trạng thái, bỏ qua nó, thay đổi trạng thái để làm những gì bạn cần, sau đó khôi phục trạng thái ban đầu.

Giống

oldState = glGet()
glBind()
glDoThings...
glSet(oldState)  // restore, in case anyone needs it just as they left it

Có lẽ, phần cứng cũ hơn có thể được thực hiện hiệu quả hơn với API thay đổi trạng thái rõ ràng; đó là một nghi thức khá kỳ lạ. Tiện ích mở rộng này ngụ ý (và chỉ cần nhìn vào danh sách quyền tác giả!) Rằng việc tránh việc tìm nạp, thiết lập, khôi phục nhảy giờ đây là một chiến thắng hiệu suất trên phần cứng hiện tại, ngay cả với tham số bổ sung trên mỗi cuộc gọi.


"cần truy vấn / stash / thay đổi / khôi phục" - làm thế nào tốt hơn với DSA?
Kromster 4/2/2015

.. mã giả được hiển thị. Với DSA, không điều gì là cần thiết. Có lẽ phần cứng hiện tại không thực sự cần trạng thái "ràng buộc", chỉ có thể truy cập tất cả khi cần.
david van brink

Chuỗi get/bind/do/sethiếm khi được sử dụng, vì 'Nhận' rất chậm. Thông thường các ứng dụng phải duy trì bản sao của các biến, vì vậy nó sẽ giảm xuống bind/do. Tôi thấy điểm mặc dù.
Kromster 4/2/2015

2
@krom nhận được từ trạng thái trình điều khiển có thể nhanh, một số trạng thái có thể không có doanh nghiệp trên GPU nên có thể nhận được từ RAM nhanh.
ratchet freak
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.