2013-05-31 12 views
5

Tôi đang đặt câu hỏi này bởi vì tôi không muốn tốn thời gian viết một số mã sao chép các chức năng của trình điều khiển OpenGL.Lẫn lộn về quản lý bộ nhớ trong OpenGL

Trình điều khiển/máy chủ OpenGL có thể chứa nhiều dữ liệu hơn thẻ video không? Giả sử, tôi có đủ RAM video để chứa 10 họa tiết. Tôi có thể yêu cầu OpenGL phân bổ 15 họa tiết mà không gặp lỗi GL_OUT_OF_MEMORY không?

Nếu tôi có thể dựa vào trình điều khiển để khéo léo gửi kết cấu/bộ đệm/đối tượng từ RAM 'bình thường' tới RAM video khi cần thì tôi không thực sự cần tạo/xóa các đối tượng này. Tôi bị giới hạn bởi RAM 'bình thường' thường rất dồi dào khi so sánh với RAM video.

+3

Vì quản lý bộ nhớ phụ thuộc vào hệ thống (có thể khác với hệ thống) và nhiều ứng dụng có thể sử dụng OpenGL cùng lúc bạn không thể chắc chắn rằng bạn có thể sử dụng toàn bộ bộ nhớ mà cạc đồ họa có. Vì vậy, bạn sẽ không nhận được xung quanh để có một _resource quản lý riêng. Điều này có thể là từ sự can thiệp cho bạn: [Xác định bộ nhớ video sẵn có] (http://stackoverflow.com/questions/4552372/determining-available-video-memory) –

+1

Có trình điều khiển nên thực hiện điều đó. Tuy nhiên nó có thể rất chậm khi nó bắt đầu trao đổi kết cấu. – jcoder

Trả lời

3

Một số thông tin bổ sung cho nhận xét của tôi không phù hợp ở đó.

Có nhiều lý do khác nhau tại sao đây không phải là một phần của OpenGL.

Nó không phải là một nhiệm vụ dễ dàng cho hệ thống/người lái xe để đoán nguồn lực nào và sẽ được yêu cầu. Trình điều khiển cho chắc chắn có thể tạo ra một heuristic nội bộ nếu tài nguyên sẽ được yêu cầu thường xuyên hoặc hiếm khi (như CPU ​​làm cho nếu báo cáo và làm trước khi thực thi mã một số phần mã trên đoán đó). Tuy nhiên, GPU sẽ không biết (mà không biết mã ứng dụng) những gì tài nguyên sẽ được yêu cầu tiếp theo. Nó thậm chí không có kiến ​​thức nơi hình học là nơi trong cảnh (bởi vì bạn làm điều này với bạn mô hình và xem martix bạn vượt qua để đổ bóng của bạn mình)

Nếu bạn, ví dụ: có một trò chơi mà bạn có thể đi qua một cảnh, bạn thường sẽ không hiển thị các phần nằm ngoài tầm nhìn. Vì vậy, GPU có thể nghĩ rằng các tài nguyên này không bắt buộc nữa, nhưng nếu bạn quay lại thì tất cả họa tiết và hình học này lại được yêu cầu và cần được di chuyển từ bộ nhớ hệ thống tới bộ nhớ gpu. . Nhưng bản thân Game Engine có, bởi vì việc sử dụng các octrees (hoặc các kỹ thuật tương tự) và các đường dẫn có thể đi được, một kiến ​​thức sâu sắc về cảnh và tài nguyên nào có thể bị loại bỏ khỏi GPU và cái nào có thể di chuyển đến GPU trong khi chơi và nơi nó sẽ là cần thiết để hiển thị một màn hình tải.

Nếu bạn nhìn vào sự phát triển của OpenGL và các tính năng trở nên không được chấp nhận, bạn sẽ thấy rằng chúng đi theo hướng để loại bỏ mọi thứ ngoại trừ các tính năng thực sự cần thiết có thể thực hiện tốt nhất bằng card đồ họa, trình điều khiển và hệ thống. Mọi thứ khác là tùy thuộc vào người dùng thực hiện trên chính nó để có được hiệu suất tốt nhất. (ví dụ: bạn tạo ma trận chiếu của mình để chuyển nó vào trình đổ bóng, vì vậy OpenGl thậm chí không biết vị trí của đối tượng được đặt trong cảnh).

+0

Điều này rất có ý nghĩa. Tôi đã không bao giờ chạm vào OpenGL trước 3.3 vì vậy tôi không biết làm thế nào bloated nó được sử dụng để được. Tôi sẽ tạo cơ chế bộ nhớ đệm của riêng mình, vì tôi biết điều gì là cần thiết khi, và tôi hạnh phúc vì tôi không thực sự cần phải tính đến những gì OpenGL làm sau lưng tôi. – Niriel

+0

@Niriel Vâng, nó là một dòng mỏng, một mặt hữu ích để biết những gì được thực hiện đằng sau hậu trường để hiểu những gì có thể dẫn đến tắc nghẽn (ví dụ: nếu nó là tốt hơn để sử dụng tra cứu kết cấu hoặc ước số thuộc tính nếu bạn vẽ dụ với một cuộc gọi hoặc nếu tái cấu trúc vấn đề sẽ cho phép song song nhiều hơn trên gpu), mặt khác nó có thể mang một rủi ro để tối ưu hóa cho việc triển khai hệ thống hoặc một số nhà cung cấp nhất định, thay vì xem xét lại vấn đề. –

7

Cách tiếp cận "bộ nhớ phong phú vì vậy tôi không cần phải xóa" là xấu, và cách tiếp cận "bộ nhớ là phong phú, vì vậy tôi sẽ không bao giờ thoát khỏi lỗi bộ nhớ" là thiếu sót.

Quản lý bộ nhớ OpenGL bị che khuất, vì lý do kỹ thuật (xem nhận xét của t.niese ở trên) và vì lý do ý thức hệ ("bạn không cần biết, bạn không muốn biết"). Mặc dù có phần mở rộng của nhà cung cấp (chẳng hạn như ATI_meminfo) cho phép bạn truy vấn một số số không ủy quyền số (không ủy quyền khi chúng có thể thay đổi mili giây tiếp theo và chúng không có hiệu ứng như phân mảnh vào tài khoản).

Nói chung, phần lớn giả định rằng bạn có thể sử dụng nhiều bộ nhớ hơn là bộ nhớ GPU chính xác.

Tuy nhiên, bạn thường không thể sử dụng tất cả bộ nhớ khả dụng.Nhiều khả năng, có giới hạn dưới "tất cả RAM sẵn có" do những hạn chế về vùng bộ nhớ (và các vùng lớn) mà trình điều khiển có thể cấp phát, khóa và DMA đến/từ. Và mặc dù bạn thường có thể sử dụng nhiều bộ nhớ hơn sẽ phù hợp trên GPU (ngay cả khi bạn sử dụng nó độc quyền), điều này không có nghĩa là phân bổ bất cẩn không thể và sẽ không cuối cùng không thành công.

Thông thường, nhưng không nhất thiết, bạn tiêu thụ càng nhiều bộ nhớ hệ thống như bộ nhớ GPU, quá (không biết, trình điều khiển thực hiện điều đó một cách bí mật). Vì trình điều khiển hoán đổi tài nguyên trong và ngoài khi cần, nó cần duy trì một bản sao. Đôi khi, cần giữ 2 hoặc 3 bản sao (ví dụ: khi phát trực tuyến hoặc cho các hoạt động ARB_copy_buffer). Đôi khi, ánh xạ một đối tượng đệm là một bản sao khác trong một khối được phân bổ đặc biệt và đôi khi bạn được phép viết thẳng vào bộ nhớ của trình điều khiển. Mặt khác, PCIe 2.0 (và PCIe 3.0 thậm chí còn hơn thế nữa) đủ nhanh để truyền các đỉnh từ bộ nhớ chính, vì vậy bạn thậm chí không cần bộ nhớ GPU (trừ bộ đệm nhỏ). Một số trình điều khiển sẽ truyền trực tiếp hình động ngay từ bộ nhớ hệ thống.

Một số GPU thậm chí không có bộ nhớ hệ thống và GPU riêng biệt (Intel Sandy Bridge hoặc AMD Fusion).

Ngoài ra, bạn nên lưu ý rằng việc xóa các đối tượng không nhất thiết phải xóa chúng (ít nhất là không phải ngay lập tức). Thông thường, với rất ít trường hợp ngoại lệ, việc xóa đối tượng OpenGL chỉ đơn thuần là xóa dự kiến ​​ngăn cản bạn tham khảo thêm đối tượng. Trình điều khiển sẽ giữ cho đối tượng có giá trị miễn là cần thiết.

Mặt khác, bạn thực sự cần xóa những gì bạn không cần nữa, và bạn nên xóa sớm. Ví dụ, bạn nên xóa một shader ngay lập tức sau khi gắn nó vào đối tượng chương trình. Điều này đảm bảo rằng bạn không bị rò rỉ tài nguyên, và nó được đảm bảo để làm việc. Xóa và xác định lại bộ đệm đỉnh hoặc điểm ảnh được sử dụng khi phát trực tuyến (bằng cách gọi glBufferData(... NULL); là thành ngữ nổi tiếng. Điều này chỉ ảnh hưởng đến chế độ xem của đối tượng và cho phép người lái tiếp tục sử dụng đối tượng cũ song song với . miễn là nó cần phải

+0

** + 1 ** để có thông tin kỹ thuật tốt đẹp –

+0

Cảm ơn các chi tiết, bây giờ nó có ý nghĩa. Ý tưởng đầu tiên của tôi là sử dụng tất cả bộ nhớ sẵn có và chờ các lỗi ngoài bộ nhớ báo hiệu khi tôi nên xóa/hoán đổi mọi thứ (yêu cầu sự tha thứ thay vì cho phép). Nhưng gl_out_of_memory không thể phục hồi được, vì vậy tôi bị bỏ lại với việc đoán/hy vọng tôi sẽ không lấp đầy nó. Tôi đoán hồ sơ là cách để đi ở đây, tôi chọn một ngân sách bộ nhớ và cố gắng ở lại bên trong. Tôi chưa từng chơi với hoạt ảnh đỉnh, vì vậy tôi không biết nhiều về luồng và không hiểu glBufferData (.. null ..). Bạn có thể giải thích điều đó không? – Niriel

3

Dưới đây là TL của tôi; DR câu trả lời, tôi khuyên bạn nên đọc Daemon và t.niese của câu trả lời cũng như:

thể tài xế OpenGL/máy chủ giữ nhiều dữ liệu hơn so với card màn hình

?

Giả sử, tôi có đủ RAM video để giữ 10 họa tiết. Tôi có thể yêu cầu OpenGL phân bổ 15 họa tiết mà không gặp lỗi GL_OUT_OF_MEMORY không?

Có. Tùy thuộc vào sự kết hợp trình điều khiển/GPU, thậm chí có thể phân bổ một kết cấu đơn lẻ vượt quá bộ nhớ của GPU và thực sự sử dụng nó để kết xuất. Tại nghề nghiệp hiện tại của tôi, tôi khai thác thực tế đó để trích xuất các lát định hướng và hình học tùy ý từ các tập dữ liệu thể tích lớn, sử dụng các trình đổ bóng để áp dụng các bộ lọc trên dữ liệu voxel tại chỗ. Hoạt động tốt nhưng không hoạt động với tốc độ khung hình tương tác.